diff --git a/CHANGELOG.md b/CHANGELOG.md index e201263..0a3793f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +**1.2.0** + +* better error output +* concurrent compiling +* errors are handled per file and won't stop the whole compilation +* function name check for build in functions +* function parameter count check for build in functions + **1.1.1** * arrays can now be declared within expressions diff --git a/src/parser/parser.go b/src/parser/parser.go index e60706f..12f9b37 100644 --- a/src/parser/parser.go +++ b/src/parser/parser.go @@ -1,7 +1,11 @@ package parser import ( + "errors" + "fmt" + "strconv" "tokenizer" + "types" ) const new_line = "\r\n" @@ -215,6 +219,12 @@ func (c *Compiler) parseForeach() { func (c *Compiler) parseFunction() { c.expect("func") + + // check for build in function + if buildin, _ := types.GetFunction(c.get().Token); buildin == true { + panic(errors.New(c.get().Token + " is a build in function, choose a different name")) + } + c.appendOut(c.get().Token+" = {", true) c.next() c.expect("(") @@ -359,30 +369,42 @@ func (c *Compiler) parseFunctionCall(out bool, name string) string { output := "" c.expect("(") - leftParams, leftParamCount := c.parseParameter(false) + params, paramCount := c.parseParameter(false) c.expect(")") - if c.accept("(") { - // buildin function - c.next() - rightParams, rightParamCount := c.parseParameter(false) - c.expect(")") + // buildin function + exists, buildin := types.GetFunction(name) - if leftParamCount > 1 { - leftParams = "[" + leftParams + "]" + if exists { + // check parameter count + if exists && paramCount < buildin.ArgsCount { + panic(errors.New("Function expected " + strconv.Itoa(buildin.ArgsCount) + " parameter but found " + strconv.Itoa(paramCount))) } - if rightParamCount > 1 { - rightParams = "[" + rightParams + "]" + if buildin.Type == types.NULL { + output = name + } else if buildin.Type == types.UNARY { + if paramCount == 1 { + output = name + " " + params + } else { + output = "[" + params + "] call " + name + } + } else { + // TODO + } + + fmt.Println(name) + /*if leftParamCount > 1 { + leftParams = "[" + leftParams + "]" } if leftParamCount > 0 { output = leftParams + " " + name + " " + rightParams } else { output = name + " " + rightParams - } + }*/ } else { - output = "[" + leftParams + "] call " + name + output = "[" + params + "] call " + name } if out { diff --git a/src/types/loader.go b/src/types/loader.go index 09732f5..3f230d3 100644 --- a/src/types/loader.go +++ b/src/types/loader.go @@ -8,6 +8,7 @@ import ( const ( // type for object types TYPE = 1 + NAN = "NaN" // types for functions NULL = 2 @@ -22,6 +23,7 @@ type FunctionType struct { Name string Type int // one of the constants NULL, UNARY, BINARY ArgsCount int + ArgsLeft int // number of args on left side for binary functions } var functions []FunctionType @@ -29,6 +31,8 @@ var functions []FunctionType // Returns function type information by name. // If not found, the first parameter will be false. func GetFunction(name string) (bool, FunctionType) { + name = strings.ToLower(name) + for _, function := range functions { if function.Name == name { return true, function @@ -74,7 +78,7 @@ func parseTypes(content string) { func parseNullFunction(line string) { parts := getParts(line) - functions = append(functions, FunctionType{parts[0], NULL, 0}) + functions = append(functions, FunctionType{parts[0], NULL, 0, 0}) } func parseUnaryFunction(line string) { @@ -85,7 +89,7 @@ func parseUnaryFunction(line string) { } args := getArgs(parts[1]) - functions = append(functions, FunctionType{parts[0], UNARY, len(args)}) + functions = append(functions, FunctionType{parts[0], UNARY, len(args) - getNaNArgs(args), 0}) } func parseBinaryFunction(line string) { @@ -96,8 +100,10 @@ func parseBinaryFunction(line string) { } argsLeft := getArgs(parts[0]) + argsLeftCount := len(argsLeft) - getNaNArgs(argsLeft) argsRight := getArgs(parts[2]) - functions = append(functions, FunctionType{parts[1], BINARY, len(argsLeft) + len(argsRight)}) + argsRightCount := len(argsRight) - getNaNArgs(argsRight) + functions = append(functions, FunctionType{parts[1], BINARY, argsLeftCount + argsRightCount, argsLeftCount}) } func getParts(line string) []string { @@ -108,3 +114,15 @@ func getParts(line string) []string { func getArgs(part string) []string { return strings.Split(part, ",") } + +func getNaNArgs(args []string) int { + nan := 0 + + for _, arg := range args { + if arg == NAN { + nan++ + } + } + + return nan +}