diff --git a/stdlib/arith.go b/stdlib/arith.go index 7a61754..a9051eb 100644 --- a/stdlib/arith.go +++ b/stdlib/arith.go @@ -29,6 +29,27 @@ import ( // perhaps we simply write out arithmetic routines that operate on the strings // then we need not worry about storage length. +func num_cast(in *ast.Token, a ast.VarTable, f ast.FuncTable) *ast.Token { + in = in.Eval(f, a, false) + if in.Tag != ast.STRING { + log.Log(log.ERR, + "only a string can successfully be cast to a number", + "number_cast") + return nil + } + + if !ast.StrIsNumber(in.Value()) { + log.Log(log.ERR, + "string failed number cast", + "number_cast") + return nil + } + + out := in.Copy() + out.Tag = ast.NUMBER + return out +} + func add(in *ast.Token, a ast.VarTable, f ast.FuncTable) *ast.Token { var res float64 diff --git a/stdlib/bool.go b/stdlib/bool.go index 328c4e7..035fa2f 100644 --- a/stdlib/bool.go +++ b/stdlib/bool.go @@ -23,6 +23,28 @@ import ( "gitlab.com/whom/shs/ast" ) +func bool_cast(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { + in = in.Eval(ft, vt, false) + if in.Tag == ast.LIST || in.Tag == ast.NUMBER { + log.Log(log.ERR, + "only strings successfully cast to bool", + "bool cast") + return nil + } + + body := in.Value() + if body != ast.TRUE && body != ast.FALSE { + log.Log(log.ERR, + "cast to bool failed", + "bool cast") + return nil + } + + res := &ast.Token{ Tag: ast.BOOL } + res.Set(body) + return res +} + func not(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { in = in.Eval(ft, vt, false) diff --git a/stdlib/stdlib.go b/stdlib/stdlib.go index 8b36763..c50b42c 100644 --- a/stdlib/stdlib.go +++ b/stdlib/stdlib.go @@ -77,7 +77,28 @@ func GenFuncTable() ast.FuncTable { Args: 1, }, - "...": &ast.Function{ + "bool": &ast.Function{ + Function: bool_cast, + Name: "bool", + TimesCalled: 0, + Args: 1, + }, + + "string": &ast.Function{ + Function: str_cast, + Name: "string", + TimesCalled: 0, + Args: 1, + }, + + "number": &ast.Function{ + Function: num_cast, + Name: "number", + TimesCalled: 0, + Args: 1, + }, + + "...": &ast.Function{ Function: expand, Name: "...", TimesCalled: 0, diff --git a/stdlib/string.go b/stdlib/string.go index ed1b861..92f9a9b 100644 --- a/stdlib/string.go +++ b/stdlib/string.go @@ -43,6 +43,13 @@ func concat(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { return t } +func str_cast(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { + body := in.Eval(ft, vt, false).String() + res := &ast.Token{ Tag: ast.STRING } + res.Set(body) + return res +} + func print_str(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { body := in.Eval(ft, vt, false).String() if body[0] != body[len(body)-1] && body[0] != '"' {