perform arg type checking and evaluation before function call

This commit is contained in:
Aidan 2020-08-21 01:37:04 -07:00
parent 90284f2d06
commit ab340ceb0a
No known key found for this signature in database
GPG key ID: 327711E983899316
9 changed files with 223 additions and 354 deletions

View file

@ -34,274 +34,314 @@ func GenFuncTable() ast.FuncTable {
"if": &ast.Function{
Function: ShsIf,
Name: "if",
TimesCalled: 0,
Args: 3,
NumArgs: 3,
EvalLazy true,
ArgLazy true
},
"while": &ast.Function{
Function: ShsWhile,
Name: "while",
TimesCalled: 0,
Args: -1,
NumArgs: -1,
EvalLazy true,
ArgLazy true,
},
"progn": &ast.Function{
Function: ShsProgn,
Name: "shs_progn",
TimesCalled: 0,
Args: -1,
NumArgs: -1,
EvalLazy: true,
ArgLazy: true,
},
"func": &ast.Function{
Function: DeclFunc,
Name: "decl_func",
TimesCalled: 0,
Args: 3,
Args: []ast.Token_t{
ast.STRING,
ast.LIST,
ast.LIST
},
EvalLazy: true,
},
"len": &ast.Function{
Function: Len,
Name: "len",
TimesCalled: 0,
Args: 1,
NumArgs: 1,
ArgLazy: true,
},
"head": &ast.Function{
Function: Head,
Name: "head",
TimesCalled: 0,
Args: 1,
Args: []ast.Token_t{
ast.LIST
},
},
"tail": &ast.Function{
Function: Tail,
Name: "tail",
TimesCalled: 0,
Args: 1,
Args: []ast.Token_t{
ast.LIST
},
},
"slice": &ast.Function{
Function: Slice,
Name: "slice",
TimesCalled: 0,
Args: 3,
Args: []ast.Token_t{
ast.NUMBER,
ast.NUMBER,
ast.LIST
},
},
"export": &ast.Function{
Function: Export,
Name: "export",
TimesCalled: 0,
Args: 2,
LazyEval: true,
Args: []ast.Token_t{
ast.STRING,
ast.LIST
},
},
"input": &ast.Function{
Function: Input,
Name: "input",
TimesCalled: 0,
Args: 1,
Args: []ast.Token_t{
ast.STRING
},
},
"load": &ast.Function{
Function: Load,
Name: "load",
TimesCalled: 0,
Args: 1,
Args: []ast.Token_t{
ast.STRING
},
},
"bool": &ast.Function{
Function: BoolCast,
Name: "bool",
TimesCalled: 0,
Args: 1,
Args: []ast.Token_t{
ast.STRING
},
},
"string": &ast.Function{
Function: StrCast,
Name: "string",
TimesCalled: 0,
Args: 1,
NumArgs: 1,
ArgLazy: true,
},
"number": &ast.Function{
Function: NumCast,
Name: "number",
TimesCalled: 0,
Args: 1,
Args: []ast.Token{
ast.NUMBER
},
},
"...": &ast.Function{
"...": &ast.Function{
Function: Expand,
Name: "...",
TimesCalled: 0,
Args: 1,
Args: []ast.Token_t{
ast.LIST
},
},
"append": &ast.Function{
Function: L_append,
Name: "append",
TimesCalled: 0,
Args: -1,
},
NumArgs: -1,
ArgLazy: true,
},
"join": &ast.Function{
Function: Join,
Name: "join",
TimesCalled: 0,
Args: 2,
Args: []ast.Token_t{
ast.STRING,
ast.LIST
},
},
"split": &ast.Function{
Function: Split,
Name: "split",
TimesCalled: 0,
Args: 2,
Args: ast.Token_t{
ast.STRING,
ast.STRING
},
},
"substr": &ast.Function{
Function: Substr,
Name: "substr",
TimesCalled: 0,
Args: 3,
Args: []ast.Token_t{
ast.NUMBER,
ast.NUMBER,
ast.STRING
},
},
"exit": &ast.Function{
Function: ExitShell,
Name: "exit",
TimesCalled: 0,
Args: 0,
Args: []ast.Token_t{},
},
"eq": &ast.Function{
Function: Eq,
Name: "==",
TimesCalled: 0,
Args: 2,
ArgLazy: true,
},
"ne": &ast.Function{
Function: Ne,
Name: "!=",
TimesCalled: 0,
Args: 2,
ArgLazy: true,
},
"<": &ast.Function{
Function: Lt,
Name: "<",
TimesCalled: 0,
Args: 2,
Args: []ast.Token_t{
ast.NUMBER,
ast.NUMBER
},
},
">": &ast.Function{
Function: Gt,
Name: ">",
TimesCalled: 0,
Args: 2,
Args: []ast.Token_t{
ast.NUMBER,
ast.NUMBER
},
},
"<=": &ast.Function{
Function: Lte,
Name: "<=",
TimesCalled: 0,
Args: 2,
Args: []ast.Token_t{
ast.NUMBER,
ast.NUMBER
},
},
">=": &ast.Function{
Function: Gte,
Name: ">=",
TimesCalled: 0,
Args: 2,
Args: []ast.Token_t{
ast.NUMBER,
ast.NUMBER
},
},
"!": &ast.Function{
Function: Not,
Name: "!",
TimesCalled: 0,
Args: 1,
Args: []ast.Token_t{
ast.Bool
},
},
"+": &ast.Function{
Function: Add,
Name: "add",
TimesCalled: 0,
Args: -1,
NumArgs: -1,
ArgLazy: true,
},
"-": &ast.Function{
Function: Sub,
Name: "sub",
TimesCalled: 0,
Args: -1,
NumArgs: -1,
ArgLazy: true,
},
"*": &ast.Function{
Function: Mult,
Name: "mult",
TimesCalled: 0,
Args: -1,
NumArgs: -1,
ArgLazy: true,
},
"/": &ast.Function{
Function: Div,
Name: "div",
TimesCalled: 0,
Args: -1,
NumArgs: -1,
ArgLazy: true,
},
"cd": &ast.Function{
Function: Cd,
Name: "changedir",
TimesCalled: 0,
Args: 1,
Args: []ast.Token_t{
ast.STRING
},
},
"concat": &ast.Function{
Function: Concat,
Name:"concatenate",
TimesCalled: 0,
Args: -1,
NumArgs: -1,
ArgLazy: true,
},
"print": &ast.Function{
Function: PrintStr,
Name: "print",
TimesCalled: 0,
Args: 1,
Args: []ast.Token_t{
ast.STRING
},
},
"l": &ast.Function{
Function: Call,
Name: "call",
TimesCalled: 0,
Args: -1,
NumArgs: -1,
ArgLazy: true,
SymLazy: true,
},
"bg": &ast.Function{
Function: Bgcall,
Name: "background call",
TimesCalled: 0,
Args: -1,
NumArgs: -1,
ArgLazy: true,
SymLazy: true,
},
"fg": &ast.Function{
Function: Fg,
Name: "foreground",
TimesCalled: 0,
Args: 1,
NumArgs: []ast.Token_t{
ast.NUMBER
},
},
"$": &ast.Function{
Function: ReadCmd,
Name: "read cmd",
TimesCalled: 0,
Args: -1,
NumnArgs: -1,
ArgLazy: true,
SymLazy: true,
},
"?": &ast.Function{
Function: GetExit,
Name:"get exit code",
TimesCalled: 0,
Args: 0,
Args: ast.Token_t{},
},
/*
@ -309,7 +349,6 @@ func GenFuncTable() ast.FuncTable {
"kill": &ast.Function{
Function: kill,
Name: "kill job",
TimesCalled: 0,
Args: 1,
},
*/
@ -317,43 +356,49 @@ func GenFuncTable() ast.FuncTable {
"jobs": &ast.Function{
Function: Jobs,
Name: "list jobs",
TimesCalled: 0,
Args: 0,
Args: ast.Token_t{},
},
"info": &ast.Function{
Function: ShInfo,
Name: "Shell Info",
TimesCalled: 0,
Args: 1,
Args: ast.Token_t{
ast.SYMBOL
},
},
"fexists": &ast.Function{
Function: Fexists,
Name: "file exists",
TimesCalled: 0,
Args: 1,
Args: []ast.Token_t{
ast.STRING
},
},
"fread": &ast.Function{
Function: Fread,
Name: "read file",
TimesCalled: 0,
Args: 1,
Args: []ast.Token_t{
ast.STRING
},
},
"fwrite": &ast.Function{
Function: Fwrite,
Name: "write file",
TimesCalled: 0,
Args: 2,
Args: []ast.Token_t{
ast.STRING,
ast.STRING
},
},
"fappend": &ast.Function{
Function: Fappend,
Name:"append to file",
TimesCalled: 0,
Args: 2,
Args: []ast.Token_t{
ast.STRING,
ast.STRING
},
},
}
@ -395,10 +440,12 @@ func ShInfo(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
funct := ast.GetFunction(in.Value(), ft)
if funct != nil {
fmt.Printf("FUNCTION\nNAME: %s\nTIMES CALLED: %s\nNUM ARGS: %d\n", funct.Name, funct.TimesCalled, funct.Args)
fmt.Printf("FUNCTION\nNAME: %s\nTIMES CALLED: %s\nNUM ARGS: %d\n", funct.Name, funct.TimesCalled, funct.NumArgs)
break
}
// TODO: print func args
fmt.Printf("UNKNOWN SYMBOL\n")
}
@ -413,14 +460,6 @@ func ShInfo(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
* Example: (print (input))
*/
func Input(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
in = in.Eval(ft, vt, false)
if in.Tag != ast.STRING && in.Tag != ast.NUMBER {
log.Log(log.ERR,
"argument to input must be a string or number",
"input")
return nil
}
prompt := in.Value()
var output string
@ -438,14 +477,6 @@ func Input(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
* Example: (load "myscript.shs")
*/
func Load(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token {
in = in.Eval(ft, vt, true)
if in.Tag != ast.STRING {
log.Log(log.ERR,
"argument to load must be a string",
"load")
return nil
}
bp := in.Value()
bp = AbsPath(bp)
util.LoadScript(bp, vt, ft)