diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..97c1779 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "macos-clang-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "/usr/bin/clang", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "macos-clang-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index ce3dcd2..61627f6 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,7 +1,4 @@ { - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { @@ -10,7 +7,17 @@ "request": "launch", "mode": "auto", "program": "main.go", - "args": ["examples/http_read.vqe"] + "args": [ + "examples/http_read.vqe" + ] + }, + { + "name": "C/C++ Runner: Debug Session", + "type": "lldb", + "request": "launch", + "args": [], + "cwd": "/Users/chakr/Library/Mobile Documents/com~apple~CloudDocs/varaq-interpreter-go", + "program": "/Users/chakr/Library/Mobile Documents/com~apple~CloudDocs/varaq-interpreter-go/build/Debug/outDebug" } ] -} +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c960231 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,37 @@ +{ + "C_Cpp_Runner.cCompilerPath": "clang", + "C_Cpp_Runner.cppCompilerPath": "clang++", + "C_Cpp_Runner.debuggerPath": "lldb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wconversion", + "-Wnull-dereference", + "-Wsign-conversion" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false +} \ No newline at end of file diff --git a/examples/aoc2022/day1/p1.vq b/examples/aoc2022/day1/p1.vq index 2030bb3..aabe457 100755 --- a/examples/aoc2022/day1/p1.vq +++ b/examples/aoc2022/day1/p1.vq @@ -15,4 +15,4 @@ vulqangan ghorqu' juv wa'boqHa' { { woD } ghobe'chugh } vangqa' -cha' +cha' chu'DonwI' diff --git a/examples/aoc2022/day1/p1.vqe b/examples/aoc2022/day1/p1.vqe index 4bedee9..60211f5 100755 --- a/examples/aoc2022/day1/p1.vqe +++ b/examples/aoc2022/day1/p1.vqe @@ -15,4 +15,4 @@ elves shatter depth sub1 { { pop } ifno } repeat -disp +disp newline diff --git a/varaq/interpreter.go b/varaq/interpreter.go index 53db90a..1f9e8c6 100644 --- a/varaq/interpreter.go +++ b/varaq/interpreter.go @@ -49,6 +49,31 @@ func pop() (Expr, error) { return res, nil } +func popExpr() (Expr, error) { + a, e := pop() + if e != nil { + return Expr{}, e + } + if a.Tok == IDENTIFIER { + a = get(a.Value.(string)) + } + return a, nil +} + +func pop2Expr() (Expr, Expr, error) { + b, e := popExpr() + if e != nil { + return Expr{}, Expr{}, e + } + + a, e := popExpr() + if e != nil { + return Expr{}, Expr{}, e + } + + return b, a, nil +} + func identifierToObj(c Expr, idx int, argv []string, w io.Writer) error { k, k_ok := c.Value.(string) if k_ok { @@ -360,7 +385,7 @@ func Interpret(code Expr, argv []string, w io.Writer) error { if list.Tok == LIST { push(Expr{BOOLEAN, nil, len(list.Exprs) == 0, 0}) } else { - return fmt.Errorf("cannot `shatter` not a list @%v", idx) + return fmt.Errorf("cannot `empty` not a list @%v", idx) } case COMPOSE: v, e := pop() @@ -581,27 +606,21 @@ func Interpret(code Expr, argv []string, w io.Writer) error { push(Expr{NUMBER, nil, math.Pow(a.Value.(float64), b.Value.(float64)), 0}) } case SQRT: - angle, e := pop() + a, e := popExpr() if e != nil { return e } - if angle.Tok == IDENTIFIER { - angle = get(angle.Value.(string)) - } - if angle.Tok == NUMBER { - push(Expr{NUMBER, nil, math.Sqrt(angle.Value.(float64)), 0}) + if a.Tok == NUMBER { + push(Expr{NUMBER, nil, math.Sqrt(a.Value.(float64)), 0}) } else { return fmt.Errorf("cannot `sqrt` value is not number or float @%v", idx) } case ADD1: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{NUMBER, nil, a.Value.(float64) + 1.0, 0}) @@ -609,13 +628,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `add1` value is not a number @%v", idx) } case SUB1: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{NUMBER, nil, a.Value.(float64) - 1.0, 0}) @@ -623,13 +639,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `sub1` value is not a number @%v", idx) } case SIN: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{NUMBER, nil, math.Sin(a.Value.(float64)), 0}) @@ -637,13 +650,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `sin` values are not numbers or floats @%v", idx) } case COS: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{NUMBER, nil, math.Cos(a.Value.(float64)), 0}) @@ -651,13 +661,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `cos` values are not numbers or floats @%v", idx) } case TAN: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{NUMBER, nil, math.Tan(a.Value.(float64)), 0}) @@ -665,13 +672,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `tan` values are not numbers or floats @%v", idx) } case ATAN: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } den, e := pop() if e != nil { @@ -687,13 +691,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `atan` values are not numbers or floats @%v", idx) } case LN: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{NUMBER, nil, math.Log(a.Value.(float64)), 0}) @@ -701,13 +702,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `ln` values are not numbers or floats @%v", idx) } case LOG: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{NUMBER, nil, math.Log10(a.Value.(float64)), 0}) @@ -715,13 +713,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `log` values are not numbers or floats @%v", idx) } case LOG3: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{NUMBER, nil, math.Log(a.Value.(float64)) / math.Log(3.0), 0}) @@ -729,13 +724,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `log3` values are not numbers or floats @%v", idx) } case CLIP: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{NUMBER, nil, math.Floor(a.Value.(float64)), 0}) @@ -743,13 +735,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `clip` values are not numbers or floats @%v", idx) } case SMOOTH: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{NUMBER, nil, math.Round(a.Value.(float64)), 0}) @@ -757,13 +746,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `smooth` values are not numbers or floats @%v", idx) } case HOWMUCH: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{NUMBER, nil, math.Abs(a.Value.(float64)), 0}) @@ -771,13 +757,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `howmuch` values are not numbers or floats @%v", idx) } case SETRAND: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { rand.Seed(int64(a.Value.(float64))) @@ -785,13 +768,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `setrand` values are not numbers or floats @%v", idx) } case RAND: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { max := a.Value.(float64) @@ -805,23 +785,17 @@ func Interpret(code Expr, argv []string, w io.Writer) error { case E: push(Expr{NUMBER, nil, 2.71828182845904523536, 0}) case ISINT: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } push(Expr{BOOLEAN, nil, a.Value.(float64) == float64(int64(a.Value.(float64))), 0}) case ISNUMBER: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } push(Expr{BOOLEAN, nil, (a.Tok == NUMBER), 0}) case NUMBERIZE: @@ -840,21 +814,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { push(Expr{NUMBER, nil, num, 0}) case ISOLATE: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER && b.Tok == NUMBER { push(Expr{NUMBER, nil, float64(int64(a.Value.(float64)) & int64(b.Value.(float64))), 0}) @@ -862,21 +825,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `isolate` values are not numbers @%v", idx) } case MIX: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER && b.Tok == NUMBER { push(Expr{NUMBER, nil, float64(int64(a.Value.(float64)) | int64(b.Value.(float64))), 0}) @@ -884,21 +836,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `mix` values are not numbers @%v", idx) } case CONTRADICT: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER && b.Tok == NUMBER { push(Expr{NUMBER, nil, float64(int64(a.Value.(float64)) ^ int64(b.Value.(float64))), 0}) @@ -906,13 +847,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `contradict` values are not numbers @%v", idx) } case COMPL: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{NUMBER, nil, float64(^int64(a.Value.(float64))), 0}) @@ -920,21 +858,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `compl` values are not numbers @%v", idx) } case SHIFTRIGHT: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER && b.Tok == NUMBER { push(Expr{NUMBER, nil, float64(int64(a.Value.(float64)) >> int64(b.Value.(float64))), 0}) @@ -942,21 +869,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `shiftright` values are not numbers @%v", idx) } case SHIFTLEFT: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER && b.Tok == NUMBER { push(Expr{NUMBER, nil, float64(int64(a.Value.(float64)) << int64(b.Value.(float64))), 0}) @@ -964,21 +880,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `shiftleft` values are not numbers @%v", idx) } case GT: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER && b.Tok == NUMBER { push(Expr{BOOLEAN, nil, a.Value.(float64) > (b.Value.(float64)), 0}) @@ -986,21 +891,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `gt` values are not numbers @%v", idx) } case LT: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER && b.Tok == NUMBER { push(Expr{BOOLEAN, nil, a.Value.(float64) < (b.Value.(float64)), 0}) @@ -1009,21 +903,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `lt` values are not numbers @%v", idx) } case EQ: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER && b.Tok == NUMBER { push(Expr{BOOLEAN, nil, a.Value.(float64) == b.Value.(float64), 0}) @@ -1031,21 +914,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `eq` values are not numbers @%v", idx) } case GE: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER && b.Tok == NUMBER { push(Expr{BOOLEAN, nil, a.Value.(float64) >= (b.Value.(float64)), 0}) @@ -1053,21 +925,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `ge` values are not numbers @%v", idx) } case LE: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER && b.Tok == NUMBER { push(Expr{BOOLEAN, nil, a.Value.(float64) <= (b.Value.(float64)), 0}) @@ -1075,21 +936,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `le` values are not numbers @%v", idx) } case NE: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER && b.Tok == NUMBER { push(Expr{BOOLEAN, nil, a.Value.(float64) != (b.Value.(float64)), 0}) @@ -1097,22 +947,16 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `ne` values are not numbers @%v", idx) } case ISNULL: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } push(Expr{BOOLEAN, nil, (a.Tok == NULL || a.Value == nil), 0}) case NEGATIVE: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == NUMBER { push(Expr{BOOLEAN, nil, a.Value.(float64) < 0.0, 0}) @@ -1120,21 +964,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `negative` values are not numbers @%v", idx) } case AND: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == BOOLEAN && b.Tok == BOOLEAN { push(Expr{BOOLEAN, nil, (a.Value.(bool) && b.Value.(bool)), 0}) @@ -1142,21 +975,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `and` values are not numbers @%v", idx) } case OR: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == BOOLEAN && b.Tok == BOOLEAN { push(Expr{BOOLEAN, nil, (a.Value.(bool) || b.Value.(bool)), 0}) @@ -1164,21 +986,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return fmt.Errorf("cannot `or` values are not numbers @%v", idx) } case XOR: - b, e := pop() + b, a, e := pop2Expr() if e != nil { return e } - if b.Tok == IDENTIFIER { - b = get(b.Value.(string)) - } - - a, e := pop() - if e != nil { - return e - } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } if a.Tok == BOOLEAN && b.Tok == BOOLEAN { push(Expr{BOOLEAN, nil, (a.Value.(bool) != b.Value.(bool)), 0}) @@ -1212,13 +1023,10 @@ func Interpret(code Expr, argv []string, w io.Writer) error { } push(Expr{STRING, nil, str, 0}) case COMPLAIN: - a, e := pop() + a, e := popExpr() if e != nil { return e } - if a.Tok == IDENTIFIER { - a = get(a.Value.(string)) - } fmt.Fprintf(os.Stderr, "%v", a.Value) case NEWLINE: fmt.Fprintf(w, "\n") @@ -1262,7 +1070,7 @@ func Interpret(code Expr, argv []string, w io.Writer) error { return e } if str.Tok != STRING { - return fmt.Errorf("cannot `servehttp` exptected a string for the port @%v", idx) + return fmt.Errorf("cannot `readall` @%v", idx) } filedata, err := ioutil.ReadFile(str.Value.(string)) // the file is inside the local directory