From aa7659e9aca19bb10c1c981081f847cc9366d934 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Tue, 21 Oct 2014 22:01:00 +0200 Subject: [PATCH 01/53] Clean repository --- .gitignore | 6 - Makefile | 33 --- README.md | 219 --------------- scripts/update.js | 14 - src/bash.ml | 21 -- src/bash.mli | 5 - src/bash_ast.ml | 51 ---- src/bash_compile.ml | 244 ---------------- src/bash_format.ml | 199 ------------- src/bash_functions.ml | 96 ------- src/bash_transform.ml | 155 ---------- src/batsh.ocp | 91 ------ src/batsh_ast.ml | 45 --- src/batsh_format.ml | 135 --------- src/errors.ml | 1 - src/errors.mli | 1 - src/formatutil.ml | 41 --- src/lexer.mll | 97 ------- src/main.ml | 130 --------- src/parser.ml | 68 ----- src/parser.mli | 11 - src/parser_yacc.mly | 198 ------------- src/semantic_checker.ml | 29 -- src/symbol_table.ml | 167 ----------- src/symbol_table.mli | 17 -- src/test.ml | 96 ------- src/winbat.ml | 21 -- src/winbat.mli | 5 - src/winbat_ast.ml | 61 ---- src/winbat_compile.ml | 544 ------------------------------------ src/winbat_format.ml | 194 ------------- src/winbat_functions.ml | 60 ---- src/winbat_transform.ml | 200 ------------- tests/arith.batsh | 16 -- tests/array.batsh | 11 - tests/assignment.batsh | 8 - tests/bash/arith.sh | 16 -- tests/bash/array.sh | 13 - tests/bash/assignment.sh | 8 - tests/bash/block.sh | 10 - tests/bash/command.sh | 5 - tests/bash/comment.sh | 6 - tests/bash/exists.sh | 12 - tests/bash/function.sh | 52 ---- tests/bash/if.sh | 32 --- tests/bash/recursion.sh | 48 ---- tests/bash/string.sh | 18 -- tests/bash/while.sh | 17 -- tests/batch/arith.bat | 70 ----- tests/batch/array.bat | 25 -- tests/batch/assignment.bat | 13 - tests/batch/block.bat | 14 - tests/batch/command.bat | 9 - tests/batch/comment.bat | 10 - tests/batch/exists.bat | 23 -- tests/batch/function.bat | 69 ----- tests/batch/if.bat | 36 --- tests/batch/recursion.bat | 73 ----- tests/batch/string.bat | 30 -- tests/batch/while.bat | 25 -- tests/block.batsh | 14 - tests/command.batsh | 5 - tests/comment.batsh | 6 - tests/exists.batsh | 11 - tests/function.batsh | 39 --- tests/if.batsh | 35 --- tests/output/arith.txt | 16 -- tests/output/array.txt | 5 - tests/output/assignment.txt | 4 - tests/output/block.txt | 4 - tests/output/command.txt | 3 - tests/output/comment.txt | 1 - tests/output/exists.txt | 3 - tests/output/function.txt | 8 - tests/output/if.txt | 6 - tests/output/recursion.txt | 19 -- tests/output/string.txt | 11 - tests/output/while.txt | 41 --- tests/recursion.batsh | 32 --- tests/string.batsh | 13 - tests/while.batsh | 18 -- 81 files changed, 4218 deletions(-) delete mode 100644 .gitignore delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 scripts/update.js delete mode 100644 src/bash.ml delete mode 100644 src/bash.mli delete mode 100644 src/bash_ast.ml delete mode 100644 src/bash_compile.ml delete mode 100644 src/bash_format.ml delete mode 100644 src/bash_functions.ml delete mode 100644 src/bash_transform.ml delete mode 100644 src/batsh.ocp delete mode 100644 src/batsh_ast.ml delete mode 100644 src/batsh_format.ml delete mode 100644 src/errors.ml delete mode 100644 src/errors.mli delete mode 100644 src/formatutil.ml delete mode 100644 src/lexer.mll delete mode 100644 src/main.ml delete mode 100644 src/parser.ml delete mode 100644 src/parser.mli delete mode 100644 src/parser_yacc.mly delete mode 100644 src/semantic_checker.ml delete mode 100644 src/symbol_table.ml delete mode 100644 src/symbol_table.mli delete mode 100644 src/test.ml delete mode 100644 src/winbat.ml delete mode 100644 src/winbat.mli delete mode 100644 src/winbat_ast.ml delete mode 100644 src/winbat_compile.ml delete mode 100644 src/winbat_format.ml delete mode 100644 src/winbat_functions.ml delete mode 100644 src/winbat_transform.ml delete mode 100644 tests/arith.batsh delete mode 100644 tests/array.batsh delete mode 100644 tests/assignment.batsh delete mode 100644 tests/bash/arith.sh delete mode 100644 tests/bash/array.sh delete mode 100644 tests/bash/assignment.sh delete mode 100644 tests/bash/block.sh delete mode 100644 tests/bash/command.sh delete mode 100644 tests/bash/comment.sh delete mode 100644 tests/bash/exists.sh delete mode 100644 tests/bash/function.sh delete mode 100644 tests/bash/if.sh delete mode 100644 tests/bash/recursion.sh delete mode 100644 tests/bash/string.sh delete mode 100644 tests/bash/while.sh delete mode 100644 tests/batch/arith.bat delete mode 100644 tests/batch/array.bat delete mode 100644 tests/batch/assignment.bat delete mode 100644 tests/batch/block.bat delete mode 100644 tests/batch/command.bat delete mode 100644 tests/batch/comment.bat delete mode 100644 tests/batch/exists.bat delete mode 100644 tests/batch/function.bat delete mode 100644 tests/batch/if.bat delete mode 100644 tests/batch/recursion.bat delete mode 100644 tests/batch/string.bat delete mode 100644 tests/batch/while.bat delete mode 100644 tests/block.batsh delete mode 100644 tests/command.batsh delete mode 100644 tests/comment.batsh delete mode 100644 tests/exists.batsh delete mode 100644 tests/function.batsh delete mode 100644 tests/if.batsh delete mode 100644 tests/output/arith.txt delete mode 100644 tests/output/array.txt delete mode 100644 tests/output/assignment.txt delete mode 100644 tests/output/block.txt delete mode 100644 tests/output/command.txt delete mode 100644 tests/output/comment.txt delete mode 100644 tests/output/exists.txt delete mode 100644 tests/output/function.txt delete mode 100644 tests/output/if.txt delete mode 100644 tests/output/recursion.txt delete mode 100644 tests/output/string.txt delete mode 100644 tests/output/while.txt delete mode 100644 tests/recursion.batsh delete mode 100644 tests/string.batsh delete mode 100644 tests/while.batsh diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 4ab74ae..0000000 --- a/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -_obuild/ -*.sublime* -ocp-build.root* -tests/oUnit* -batsh -oUnit-anon.cache diff --git a/Makefile b/Makefile deleted file mode 100644 index bfb1ca9..0000000 --- a/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -build: _obuild - ocp-build build batsh - ln -sf _obuild/batsh/batsh.asm batsh - -LIBDIR=$(CAML_LD_LIBRARY_PATH)/.. -BATSHDIR=$(LIBDIR)/batsh - -install: build - ocp-build install batsh-lib batsh -install-lib "$(LIBDIR)" - # This is an unly wordaround for fixing the generated META file - sed -i 's/ camlp4lib//g' "$(LIBDIR)/META.batsh" - sed -i 's/ camlp4lib//g' "$(LIBDIR)/META.batsh-lib" - -uninstall: - ocp-build uninstall - -test: build - ocp-build build test - @./_obuild/test/test.asm - -update: build - node scripts/update.js | bash - -_obuild: - ocp-build init - -clean: - ocp-build clean - -distclean: - rm -rf _obuild - -.PHONY: build diff --git a/README.md b/README.md deleted file mode 100644 index 44eeea2..0000000 --- a/README.md +++ /dev/null @@ -1,219 +0,0 @@ -# Batsh - -Batsh is a simple programming language that compiles to Bash and Windows [Batch](http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/batch.mspx). -It enables you to write your script once runs on all platforms without **any** additional dependency. - -Both Bash and Batch are messy to read and tricky to write due to historical reasons. -You have to spend a lot of time learning either of them and write platform-dependent code for each operating system. -I have wasted lots of time in my life struggling with bizare syntaxes and unreasonable behaviors of them, and do not want to waste any more. - -If you happen to be a maintainer of a cross-platform tool which relies on Bash on Linux/Mac and Batch on Windows as "glue code", and found it painful to "synchronize" between them, you would definitely like to try Batsh. - -## How to get it - -### The easiest way - -[Try it online: http://batsh.org](http://batsh.org/) - -### Install from OPAM - -Batsh is implemented in OCaml and managed by [OPAM](http://opam.ocaml.org/pkg/batsh/0.0.5/). - -1. Install OPAM. See [instructions](http://opam.ocaml.org/doc/Quick_Install.html). -2. Switch to the latest version (or at least 4.00.1) of OCaml by running `opam switch`. -3. Install Batsh: `opam install batsh` - -### Build from source - -You have to install OCaml (version 4.00.1 or higher) development environment before compiling Batsh from source code, and follow steps below: - -1. Download source code of Batsh from [releases](https://github.com/BYVoid/Batsh/releases) or clone with git. -2. Uncompress source code tarball. -3. `make` -4. `make install` -5. Run: `batsh` - -#### Dependencies - -If there is any missing dependency, you can install them by running `opam install ocp-build core ounit dlist cmdliner` - -* [ocp-build](http://www.typerex.org/ocp-build.html): Build framework. -* [core](http://janestreet.github.io/): An industrial strength alternative to OCaml's standard library. -* [ounit](http://ounit.forge.ocamlcore.org/): Unit test framework. -* [dlist](https://github.com/BYVoid/Dlist): A purely functional list-like data structure supporting O(1) concatenation. -* [cmdliner](http://erratique.ch/software/cmdliner): Command line interfaces parser. - -## Syntax - -The syntax of Batsh is [C-based](https://en.wikipedia.org/wiki/List_of_C-based_programming_languages) (derived from C programming language). -If you have learned C, Java, C++ or JavaScript, Batsh is quite easy for you. - -### Assignment - -```javascript -a = 1; -b = "string"; -c = [1, 2, "str", true, false]; -``` - -### Expression - -```javascript -a = 1 + 2; -b = a * 7; -c = "Con" ++ "cat"; -d = c ++ b; -``` - -### Command - -```javascript -// On UNIX -output = ls(); -// On Windows -output = dir(); -// Platform independent -output = readdir(); - -// Test existence -ex = exists("file.txt"); -``` - -### If condition - -```javascript -a = 3; -if (a > 2) { - println("Yes"); -} else { - println("No"); -} -``` - -### Loop - -```javascript -// Fibonacci -n = 0; -i = 0; -j = 1; -while (n < 60) { - k = i + j; - i = j; - j = k; - n = n + 1; - println(k); -} -``` - -### Function - -```javascript -v1 = "Global V1"; -v2 = "Global V2"; -function func(p) { - v1 = "Local " ++ p; - global v2; - v2 = "V3 Modified."; -} -func("Var"); -``` - -### Recursion - -```javascript -function fibonacci(num) { - if (num == 0) { - return 0; - } else if (num == 1) { - return 1; - } else { - return (fibonacci(num - 2) + fibonacci(num - 1)); - } -} -println(fibonacci(8)); -``` - -### [More examples](https://github.com/BYVoid/Batsh/tree/master/tests) - -## Built-in functions - -In order to make script cross-platform, Batsh provided some "built-in" functions that will compile to platform-dependent code. It is assumed that Bash script runs on Linux or Mac OS and Batch script runs on Windows (XP or higher), which means Cygwin or wine are not supported. - -### `print(text, ...)` - -Prints a text string to console without a newline. - -### `println(text, ...)` - -Prints a text string to console with a new line (LF for bash, CRLF for batch). - -### `call(path, arg, ...)` - -Runs command from path through shell. - -### `bash(rawStatement)` - -Put `rawStatement` into compiled code for Bash. Ignore for Windows Batch. - -### `batch(rawStatement)` - -Put `rawStatement` into compiled code for Windows Batch. Ignore for Bash. - -### `readdir(path)` - -Equals to `ls` and `dir /w`. - -### `exists(path)` - -Test existence of given path. - -## Command Line Usage - -``` -NAME - batsh - A language that compiles to Bash and Windows Batch. - -SYNOPSIS - batsh COMMAND ... - -COMMANDS - bash - Compile to Bash script. - - batsh - Format source file. - - winbat - Compile to Windows Batch script. - -OPTIONS - --help[=FMT] (default=pager) - Show this help in format FMT (pager, plain or groff). - - --version - Show version information. -``` - -## Why not Python/Ruby/Node.js/Lua - -Yes you can use any of them as platform-independent glue code. But there are several disadvantages: - -1. None of them is **preinstalled on all platforms** (including Windows). -2. Functionalities like process piping are not convenient to use. -3. Hard to integrate with existing code written in Bash or Batch. - -Those reasons are why I developed Batsh. - -## License - -[MIT](http://opensource.org/licenses/MIT) - -## Contributors - -* [Carbo Kuo](https://github.com/BYVoid) -* [Song Zhang](http://www.linkedin.com/pub/song-zhang/76/632/b51) -* [Anthony Chan](https://github.com/anthonyhchan) -* [jeb-de](https://github.com/jeb-de) -* [Al Ramirez](https://github.com/mirez) -* [Nixola](https://github.com/Nixola) diff --git a/scripts/update.js b/scripts/update.js deleted file mode 100644 index f541386..0000000 --- a/scripts/update.js +++ /dev/null @@ -1,14 +0,0 @@ -var fs = require("fs"); -var path = require("path"); - -var files = fs.readdirSync("tests"); -for (var i = 0; i < files.length; i++) { - var file = files[i]; - var ext = path.extname(file); - if (ext == '.batsh') { - var name = path.basename(file, ext); - console.log('./batsh bash tests/' + name + '.batsh > tests/bash/' + name + '.sh'); - console.log('./batsh winbat tests/' + name + '.batsh > tests/batch/' + name + '.bat'); - console.log('bash tests/bash/' + name + '.sh > tests/output/' + name + '.txt'); - } -} diff --git a/src/bash.ml b/src/bash.ml deleted file mode 100644 index 695b87a..0000000 --- a/src/bash.ml +++ /dev/null @@ -1,21 +0,0 @@ -type t = { - batsh : Parser.t; - bash_ast : Bash_ast.t; - bash_ast_expanded : Bash_ast.t; -} - -let compile (batsh : Parser.t) : t = - let bash_ast = Bash_compile.compile batsh in - let bash_ast_expanded = Bash_functions.expand bash_ast in - {batsh; bash_ast; bash_ast_expanded} - -let print (bash : t) : string = - let buf = Buffer.create 1024 in - Bash_format.print buf bash.bash_ast_expanded; - Buffer.contents buf - -let ast ?(expand_functions=true) (bash : t) : Bash_ast.t = - if expand_functions then - bash.bash_ast_expanded - else - bash.bash_ast diff --git a/src/bash.mli b/src/bash.mli deleted file mode 100644 index f5827db..0000000 --- a/src/bash.mli +++ /dev/null @@ -1,5 +0,0 @@ -type t - -val compile : Parser.t -> t -val print : t -> string -val ast : ?expand_functions:bool -> t -> Bash_ast.t diff --git a/src/bash_ast.ml b/src/bash_ast.ml deleted file mode 100644 index 808a61e..0000000 --- a/src/bash_ast.ml +++ /dev/null @@ -1,51 +0,0 @@ -open Core_kernel.Std - -type identifier = string - -and identifiers = identifier list - -and leftvalue = - | Identifier of identifier - | ListAccess of (leftvalue * arithmetic) - | EntireList of leftvalue - | Cardinal of leftvalue - -and arithmetic = - | Leftvalue of leftvalue - | Int of int - | Float of float - | ArithUnary of (string * arithmetic) - | ArithBinary of (string * arithmetic * arithmetic) - -and expression = - | Variable of leftvalue - | String of string - | Result of arithmetic - | StrBinary of (string * expression * expression) - | TestUnary of (string * expression) - | Command of (expression * expressions) - | List of expressions - | Raw of string - -and expressions = expression list - -and statement = - | Comment of string - | Local of identifier - | Assignment of (leftvalue * expression) - | Expression of expression - | If of (expression * statement) - | IfElse of (expression * statement * statement) - | While of (expression * statement) - | Block of statements - | Return - | Empty - -and statements = statement list - -and toplevel = - | Statement of statement - | Function of (identifier * statements) - -and t = toplevel list -with sexp_of diff --git a/src/bash_compile.ml b/src/bash_compile.ml deleted file mode 100644 index 4f1c082..0000000 --- a/src/bash_compile.ml +++ /dev/null @@ -1,244 +0,0 @@ -open Core_kernel.Std -open Bash_ast - -module BAST = Batsh_ast - -let is_arith (expr: BAST.expression) :bool = - match expr with - | BAST.String _ - | BAST.List _ - | BAST.StrCompare _ - | BAST.Concat _ - | BAST.Call _ -> - false - | BAST.Bool _ - | BAST.Int _ - | BAST.Float _ - | BAST.Leftvalue _ - | BAST.ArithUnary _ - | BAST.ArithBinary _ -> - true - -let is_leftvalue (expr : BAST.expression) : bool = - match expr with - | BAST.Leftvalue _ -> true - | _ -> false - -let rec compile_expr_to_arith - (expr: BAST.expression) - ~(symtable: Symbol_table.t) - ~(scope: Symbol_table.Scope.t) - :arithmetic = - let compile_expr_to_arith = compile_expr_to_arith ~symtable ~scope in - match expr with - | BAST.Bool false -> Int 0 - | BAST.Bool true -> Int 1 - | BAST.Int number -> Int number - | BAST.Float number -> Float number - | BAST.Leftvalue lvalue -> - Leftvalue (compile_leftvalue lvalue ~symtable ~scope) - | BAST.ArithUnary (operator, expr) -> - ArithUnary (operator, compile_expr_to_arith expr) - | BAST.ArithBinary (operator, left, right) -> - ArithBinary (operator, - compile_expr_to_arith left, - compile_expr_to_arith right) - | BAST.String _ - | BAST.List _ - | BAST.StrCompare _ - | BAST.Concat _ - | BAST.Call _ -> - assert false - -and compile_expr - (expr: BAST.expression) - ~(symtable: Symbol_table.t) - ~(scope: Symbol_table.Scope.t) - : expression = - if is_arith expr && not (is_leftvalue expr) then - Result (compile_expr_to_arith expr ~symtable ~scope) - else - let compile_expr = compile_expr ~symtable ~scope in - match expr with - | BAST.Bool false -> String "false" - | BAST.Bool true -> String "true" - | BAST.Int number -> String (string_of_int number) - | BAST.Float number -> String (Float.to_string number) - | BAST.String str -> String str - | BAST.Leftvalue lvalue -> - Variable (compile_leftvalue lvalue ~symtable ~scope) - | BAST.StrCompare (operator, left, right) -> - StrBinary (operator, - compile_expr left, - compile_expr right) - | BAST.Concat (left, right) -> - StrBinary ("++", - compile_expr left, - compile_expr right) - | BAST.Call (ident, exprs) -> - compile_call (ident, exprs) ~symtable ~scope - | BAST.List exprs -> - List (List.map exprs ~f: compile_expr) - | BAST.ArithUnary _ - | BAST.ArithBinary _ -> - assert false - -and compile_call - (ident, exprs) - ~(symtable: Symbol_table.t) - ~(scope: Symbol_table.Scope.t) - : expression = - match ident with - | "exists" -> - let params_1 params = - match params with - | param :: _ -> param - | _ -> failwith ("exists must have only 1 parameter.") - in - let param = compile_expr (params_1 exprs) ~symtable ~scope in - TestUnary ("-e", param) - | _ -> - let params = List.map exprs ~f: (compile_expr ~symtable ~scope) in - Command (String ident, params) - -and compile_leftvalue - (lvalue: BAST.leftvalue) - ~(symtable: Symbol_table.t) - ~(scope: Symbol_table.Scope.t) - :leftvalue = - match lvalue with - | BAST.Identifier ident -> - Identifier ident - | BAST.ListAccess (lvalue, expr) -> - ListAccess (compile_leftvalue lvalue ~symtable ~scope, - compile_expr_to_arith expr ~symtable ~scope) - -let rec compile_statement - (stmt: BAST.statement) - ~(symtable: Symbol_table.t) - ~(scope: Symbol_table.Scope.t) - :statement = - match stmt with - | BAST.Comment comment -> - Comment comment - | BAST.Assignment assignment -> - compile_assignment assignment ~symtable ~scope - | BAST.Expression expr -> - Expression (compile_expr expr ~symtable ~scope) - | BAST.If (expr, stmt) -> - compile_if_statement expr stmt ~symtable ~scope - | BAST.IfElse (expr, thenStmt, elseStmt) -> - compile_if_else_statement expr thenStmt elseStmt ~symtable ~scope - | BAST.While (expr, stmt) -> - compile_while_statement expr stmt ~symtable ~scope - | BAST.Block stmts -> - Block (List.map stmts ~f: (compile_statement ~symtable ~scope)) - | BAST.Global _ -> - Empty - | BAST.Return (Some expr) -> - let call_stmt = BAST.Expression (BAST.Call ("print", [expr])) in - Block [compile_statement call_stmt ~symtable ~scope; Return] - | BAST.Return None -> - Return - | BAST.Empty -> - Empty - -and compile_assignment - (lvalue, expr) - ~(symtable: Symbol_table.t) - ~(scope: Symbol_table.Scope.t) - : statement = - let lvalue = compile_leftvalue lvalue ~symtable ~scope in - let expr_compiled = compile_expr expr ~symtable ~scope in - let split_test (test_stmt : statement) : statement = - let assignment = Assignment - (lvalue, - Result ( - ArithUnary ("!", - Leftvalue (Identifier "?")))) - in - Block [test_stmt; assignment] - in - match expr with - | BAST.StrCompare _ -> - let test_stmt = Expression expr_compiled in - split_test test_stmt - | BAST.Call (("exists", _) as call) -> - let test_expr = compile_call call ~symtable ~scope in - split_test (Expression test_expr) - | _ -> - Assignment (lvalue, expr_compiled) - -and compile_if_statement - (expr: BAST.expression) - stmt - ~(symtable: Symbol_table.t) - ~(scope: Symbol_table.Scope.t) - :statement = - If (compile_expr expr ~symtable ~scope, - compile_statement stmt ~symtable ~scope) - -and compile_if_else_statement - (expr: BAST.expression) - (thenStmt: BAST.statement) - (elseStmt: BAST.statement) - ~(symtable: Symbol_table.t) - ~(scope: Symbol_table.Scope.t) - :statement = - IfElse (compile_expr expr ~symtable ~scope, - compile_statement thenStmt ~symtable ~scope, - compile_statement elseStmt ~symtable ~scope) - -and compile_while_statement - (expr: BAST.expression) - stmt - ~(symtable: Symbol_table.t) - ~(scope: Symbol_table.Scope.t) - :statement = - While (compile_expr expr ~symtable ~scope, - compile_statement stmt ~symtable ~scope) - -let compile_statements - (stmts: BAST.statements) - ~(symtable: Symbol_table.t) - ~(scope: Symbol_table.Scope.t) - :statements = - List.map stmts ~f: (compile_statement ~symtable ~scope) - -let compile_function - (name, params, stmts) - ~(symtable: Symbol_table.t) - :toplevel = - let scope = Symbol_table.scope symtable name in - let body = compile_statements stmts ~symtable ~scope in - let locals = Symbol_table.Scope.fold scope - ~init: [] - ~f: (fun ident global acc -> - if global then - acc - else - (Local ident) :: acc - ) - in - let param_defines = List.mapi params ~f: (fun i param -> - Assignment (Identifier param, - Variable (Identifier (string_of_int (i + 1)))) - ) - in - Function (name, List.concat [locals; param_defines; body]) - -let compile_toplevel - ~(symtable: Symbol_table.t) - (topl: BAST.toplevel) - :toplevel = - match topl with - | BAST.Statement stmt -> - Statement (compile_statement stmt ~symtable - ~scope: (Symbol_table.global_scope symtable)) - | BAST.Function func -> - compile_function func ~symtable - -let compile (batsh : Parser.t) : t = - let symtable = Parser.symtable batsh in - let program = Bash_transform.split (Parser.ast batsh) ~symtable in - List.map program ~f: (compile_toplevel ~symtable) diff --git a/src/bash_format.ml b/src/bash_format.ml deleted file mode 100644 index d1a1817..0000000 --- a/src/bash_format.ml +++ /dev/null @@ -1,199 +0,0 @@ -open Core_kernel.Std -open Bash_ast - -let rec print_lvalue_partial (buf : Buffer.t) (lvalue : leftvalue) = - match lvalue with - | Identifier ident -> - Buffer.add_string buf ident - | ListAccess (lvalue, arith) -> - bprintf buf "%a[%a]" - print_lvalue_partial lvalue - (print_arith ~paren:false) arith - | EntireList lvalue -> - bprintf buf "%a[@]" print_lvalue_partial lvalue - | Cardinal lvalue -> - bprintf buf "#%a" print_lvalue_partial lvalue - -and print_lvalue (buf : Buffer.t) (lvalue : leftvalue) ~(quote : bool) = - let quote = if quote then "\"" else "" in - match lvalue with - | Identifier ident -> - bprintf buf "%s$%a%s" quote print_lvalue_partial lvalue quote - | ListAccess _ - | EntireList _ - | Cardinal _ -> - bprintf buf "%s${%a}%s" quote print_lvalue_partial lvalue quote - -and print_arith - ?(paren = true) - (buf : Buffer.t) - (expr: arithmetic) - = - match expr with - | Leftvalue lvalue -> print_lvalue buf lvalue ~quote:false - | Int number -> Buffer.add_string buf (string_of_int number) - | Float number -> Buffer.add_string buf (Float.to_string number) - | ArithUnary (operator, arith) -> - if paren then - bprintf buf "%s(%a)" operator (print_arith ~paren:true) arith - else - bprintf buf "%s%a" operator (print_arith ~paren:true) arith - | ArithBinary binary -> - if paren then - bprintf buf "(%a)" print_arith_binary binary - else - print_arith_binary buf binary - -and print_arith_binary - (buf : Buffer.t) - (operator, left, right) - = - let operator = match operator with - | "===" -> "==" - | "!==" -> "!=" - | _ -> operator - in - bprintf buf "%a %s %a" - (print_arith ~paren:true) left - operator - (print_arith ~paren:true) right - -let rec print_expression buf (expr: expression) = - match expr with - | Variable lvalue | Result Leftvalue lvalue -> - print_lvalue buf lvalue ~quote:true - | String str -> - bprintf buf "\"%s\"" (Formatutil.escape str) - | Result arith -> - bprintf buf "$((%a))" (print_arith ~paren:false) arith - | StrBinary binary -> - print_str_binary buf binary - | TestUnary test -> - print_test_unary buf test - | Command cmd -> - bprintf buf "$(%a)" print_command cmd - | List exprs -> - Buffer.add_string buf "("; - let num_exprs = List.length exprs in - List.iteri exprs ~f: (fun i expr -> - print_expression buf expr; - if i <> num_exprs - 1 then - Buffer.add_string buf " " - ); - Buffer.add_string buf ")" - | Raw str -> - Buffer.add_string buf str - -and print_str_binary (buf: Buffer.t) (operator, left, right) = - match operator with - | "++" -> - bprintf buf "%a%a" print_expression left print_expression right - | "==" -> - bprintf buf "[ %a == %a ]" print_expression left print_expression right - | "!=" -> - bprintf buf "[ %a != %a ]" print_expression left print_expression right - | _ -> - failwith ("Unknown operator: " ^ operator) - -and print_test_unary (buf: Buffer.t) (operator, expr) = - bprintf buf "[ %s %a ]" operator print_expression expr - -and print_command (buf: Buffer.t) (name, params) = - bprintf buf "%a %a" - print_expression name - (Formatutil.print_separate_list ~f: print_expression ~separator: " ") params - -let rec print_statement buf (stmt: statement) ~(indent: int) = - let () = match stmt with - | Block _ -> () - | _ -> - Formatutil.print_indent buf indent in - match stmt with - | Comment comment -> - bprintf buf "#%s" comment - | Local ident -> - bprintf buf "local %s" ident - | Assignment (lvalue, expr) -> - bprintf buf "%a=%a" - print_lvalue_partial lvalue - print_expression expr - | Expression (Command cmd) -> - print_command buf cmd - | Expression expr -> - print_expression buf expr - | If (expr, stmts) -> - print_if buf expr stmts ~indent - | IfElse (expr, then_stmts, else_stmts) -> - print_if_else buf expr then_stmts else_stmts ~indent - | While (expr, stmts) -> - print_while buf expr stmts ~indent - | Block [] -> - Buffer.add_string buf "-" - | Block stmts -> - print_statements buf stmts ~indent - | Return -> - Buffer.add_string buf "return" - | Empty -> () - -and print_condition (buf : Buffer.t) (expr : expression) = - match expr with - | StrBinary (("==", _, _) as bin) - | StrBinary (("!=", _, _) as bin) -> - print_str_binary buf bin - | TestUnary test -> - print_test_unary buf test - | _ -> - bprintf buf "[ %a == 1 ]" print_expression expr - -and print_if_while - (buf: Buffer.t) - (expr: expression) - (stmt: statement) - (first: string) - (second: string) - (third: string) - ~(indent: int) = - let print_statement_indented = print_statement ~indent: (indent + 2) in - bprintf buf "%s %a; %s\n%a%a\n%s" - first (* if/while *) - print_condition expr - second (* then/do *) - print_statement_indented stmt - Formatutil.print_indent indent - third (* fi/done *) - -and print_if buf (expr: expression) (stmt: statement) ~(indent: int) = - print_if_while buf expr stmt "if" "then" "fi" ~indent - -and print_if_else - (buf: Buffer.t) - (expr: expression) - (then_stmt: statement) - (else_stmt: statement) - ~(indent: int) = - let print_statement_indented = print_statement ~indent: (indent + 2) in - bprintf buf "if %a; then\n%a\n%aelse\n%a\n%afi" - print_condition expr - print_statement_indented then_stmt - Formatutil.print_indent indent - print_statement_indented else_stmt - Formatutil.print_indent indent - -and print_while buf (expr: expression) (stmt: statement) ~(indent: int) = - print_if_while buf expr stmt "while" "do" "done" ~indent - -and print_statements: Buffer.t -> statements -> indent:int -> unit = - Formatutil.print_statements ~f: print_statement - -let print_function (buf: Buffer.t) (name, stmts) = - bprintf buf "function %s {\n%a\n}" - name - (print_statements ~indent: 2) stmts - -let print_toplevel (buf: Buffer.t) (topl: toplevel) ~indent = - match topl with - | Statement stmt -> print_statement buf stmt ~indent - | Function func -> print_function buf func - -let print (buf: Buffer.t) (program: t) :unit = - Formatutil.print_statements buf program ~f: print_toplevel ~indent: 0 diff --git a/src/bash_functions.ml b/src/bash_functions.ml deleted file mode 100644 index 696a80a..0000000 --- a/src/bash_functions.ml +++ /dev/null @@ -1,96 +0,0 @@ -open Core_kernel.Std -open Bash_ast - -let rec expand_leftvalue (lvalue : leftvalue) : leftvalue = - match lvalue with - | Identifier _ | EntireList _ | Cardinal _ -> - lvalue - | ListAccess (lvalue, arith) -> - ListAccess (expand_leftvalue lvalue, arith) - -let rec expand_expression (expr : expression) : expression = - match expr with - | Variable lvalue -> - Variable (expand_leftvalue lvalue) - | StrBinary (operator, left, right) -> - StrBinary (operator, expand_expression left, expand_expression right) - | Command (name, exprs) -> - expand_command name exprs - | List (exprs) -> - List (expand_expressions exprs) - | String _ | Result _ | Raw _ | TestUnary _ -> expr - -and expand_expressions (exprs : expressions) : expressions = - List.map exprs ~f: expand_expression - -and expand_command (name : expression) (exprs : expressions) = - let exprs = expand_expressions exprs in - match name with - | String "bash" -> ( - match exprs with - | [String raw] -> - Raw raw - | _ -> - failwith "bash raw command must have 1 argument of string literal." - ) - | String "batch" -> - failwith "batch raw command can not be a part of expression." - | String "println" -> - Command (String "echo", (String "-e") :: exprs) - | String "print" -> - Command (String "echo", (String "-ne") :: exprs) - | String "call" -> ( - match exprs with - | cmd :: args -> - expand_command cmd args - | [] -> - failwith "call must have at least 1 argument." - ) - | String "len" -> ( - match exprs with - | [Variable lvalue] | [Result (Leftvalue lvalue)] -> - Variable (Cardinal (EntireList lvalue)) - | _ -> - failwith "len must have exactly 1 argument." - ) - | String "readdir" -> - Command (String "ls", exprs) - | _ -> - Command (name, exprs) - -let rec expand_statement (stmt : statement) : statement = - match stmt with - | Assignment (lvalue, expr) -> - Assignment (expand_leftvalue lvalue, expand_expression expr) - | Expression (Command (String "batch", _)) -> - Empty - | Expression expr -> - Expression (expand_expression expr) - | If (expr, stmt) -> - If (expand_expression expr, expand_statement stmt) - | IfElse (expr, then_stmt, else_stmt) -> - IfElse (expand_expression expr, - expand_statement then_stmt, - expand_statement else_stmt) - | While (expr, stmt) -> - While (expand_expression expr, expand_statement stmt) - | Block stmts -> - Block (expand_statements stmts) - | Comment _ | Local _ | Empty | Return -> stmt - -and expand_statements (stmts: statements) : statements = - List.map stmts ~f: expand_statement - -let expand_function ((name : identifier), (stmts : statements)) - : (identifier * statements) = - (name, expand_statements stmts) - -let expand_toplevel (topl : toplevel) : toplevel = - match topl with - | Statement stmt -> - Statement (expand_statement stmt) - | Function func -> - Function (expand_function func) - -let expand (ast : t) : t = - List.map ast ~f: expand_toplevel diff --git a/src/bash_transform.ml b/src/bash_transform.ml deleted file mode 100644 index 6e7a954..0000000 --- a/src/bash_transform.ml +++ /dev/null @@ -1,155 +0,0 @@ -open Core_kernel.Std -open Batsh_ast - -let rec split_expression - ?(split_string = false) - ?(split_list = true) - ?(split_strcmp = true) - (expr : expression) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : (statement Dlist.t * expression) = - let split_binary ?(split_string = false) (left, right) = - let assignments_left, left = split_expression left - ~split_string ~symtable ~scope - in - let assignments_right, right = split_expression right - ~split_string ~symtable ~scope - in - (Dlist.append assignments_left assignments_right), (left, right) - in - let split_when ~cond current_assignments new_expr = - let split_expr_to_assignment assignments expr - : (statement Dlist.t * expression) = - let ident = Symbol_table.Scope.add_temporary_variable scope in - let variable = Identifier ident in - let assignments = Dlist.append - assignments - (Dlist.of_list [Assignment (variable, expr)]) - in - assignments, (Leftvalue variable) - in - if cond then - split_expr_to_assignment current_assignments new_expr - else - current_assignments, new_expr - in - match expr with - | Bool _ | Int _ | Float _ | Leftvalue _ -> - Dlist.empty () , expr - | ArithUnary (operator, expr) -> - let assignments, expr = split_expression expr - ~split_string:true ~symtable ~scope - in - assignments, ArithUnary (operator, expr) - | ArithBinary (operator, left, right) -> - let assignments, (left, right) = split_binary (left, right) - ~split_string:true - in - assignments, ArithBinary (operator, left, right) - | String str -> - split_when ~cond:split_string (Dlist.empty ()) (String str) - | Concat (left, right) -> - let assignments, (left, right) = split_binary (left, right) in - split_when ~cond:split_string assignments (Concat (left, right)) - | StrCompare (operator, left, right) -> - let assignments, (left, right) = split_binary (left, right) in - split_when ~cond:split_strcmp assignments (StrCompare (operator, left, right)) - | Call (ident, exprs) -> - let assignments, exprs = split_expressions exprs ~symtable ~scope in - split_when ~cond:split_string assignments (Call (ident, exprs)) - | List exprs -> - let assignments, exprs = split_expressions exprs ~symtable ~scope in - split_when ~cond:split_list assignments (List exprs) - -and split_expressions - (exprs : expressions) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : (statement Dlist.t * expressions) = - let assignments, exprs = List.fold exprs ~init: (Dlist.empty (), []) - ~f: (fun (assignments_acc, exprs_acc) expr -> - let assignments, expr = split_expression expr ~symtable ~scope in - (Dlist.append assignments assignments_acc, expr :: exprs_acc) - ) - in - assignments, List.rev exprs - -let rec split_statement - (stmt : statement) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : statement = - let prepend_assignments (assignments : statement Dlist.t) stmt : statement = - if Dlist.length assignments = 0 then - stmt - else - Block (Dlist.to_list (Dlist.append assignments (Dlist.of_list [stmt]))) - in - match stmt with - | Empty | Global _ | Comment _ | Return None -> - stmt - | Expression expr -> - let assignments, expr = split_expression expr - ~split_list:false ~symtable ~scope - in - prepend_assignments assignments (Expression expr) - | Assignment (lvalue, expr) -> - let assignments, expr = split_expression expr - ~split_list:false ~split_strcmp:false ~symtable ~scope - in - prepend_assignments assignments (Assignment (lvalue, expr)) - | If (expr, stmt) -> - let assignments, expr = split_expression expr - ~split_strcmp:false ~symtable ~scope - in - let stmt = split_statement stmt ~symtable ~scope in - prepend_assignments assignments (If (expr, stmt)) - | IfElse (expr, then_stmt, else_stmt) -> - let assignments, expr = split_expression expr - ~split_strcmp:false ~symtable ~scope - in - let then_stmt = split_statement then_stmt ~symtable ~scope in - let else_stmt = split_statement else_stmt ~symtable ~scope in - prepend_assignments assignments (IfElse (expr, then_stmt, else_stmt)) - | While (expr, stmt) -> - let assignments, expr = split_expression expr - ~split_strcmp:false ~symtable ~scope - in - let stmt = split_statement stmt ~symtable ~scope in - prepend_assignments assignments (While (expr, stmt)) - | Block stmts -> - Block (split_statements stmts ~symtable ~scope) - | Return (Some expr) -> - let assignments, expr = split_expression expr ~symtable ~scope in - prepend_assignments assignments (Return (Some expr)) - -and split_statements - (stmts : statements) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : statements = - List.map stmts ~f: (split_statement ~symtable ~scope) - -let split_function - (name, params, stmts) - ~(symtable : Symbol_table.t) - = - let scope = Symbol_table.scope symtable name in - let body = split_statements stmts ~symtable ~scope in - name, params, body - -let split_toplevel - (topl : toplevel) - ~(symtable : Symbol_table.t) - : toplevel = - match topl with - | Statement stmt -> - Statement (split_statement stmt ~symtable - ~scope: (Symbol_table.global_scope symtable)) - | Function func -> - Function (split_function func ~symtable) - -(* Split arithmetic expressions, list literal and command call *) -let split (ast : Batsh_ast.t) ~(symtable : Symbol_table.t) : Batsh_ast.t = - List.map ast ~f: (split_toplevel ~symtable) diff --git a/src/batsh.ocp b/src/batsh.ocp deleted file mode 100644 index fd98bb6..0000000 --- a/src/batsh.ocp +++ /dev/null @@ -1,91 +0,0 @@ -authors = ["Carbo Kuo "] -license = ["BSD3"] -version = "0.0.5" -description = "A language that compiles to Bash and Windows Batch." - -begin library "batsh-lib" - sort = true - files = [ - "bash.ml" - "bash_ast.ml" (syntax = "sexplib-syntax") - "bash_compile.ml" - "bash_format.ml" - "bash_functions.ml" - "bash_transform.ml" - "batsh_ast.ml" (syntax = "sexplib-syntax") - "batsh_format.ml" - "errors.ml" - "formatutil.ml" - "lexer.mll" - "parser.ml" - "parser_yacc.mly" - "semantic_checker.ml" - "symbol_table.ml" (syntax = "sexplib-syntax") - "version.ml" (ocp2ml) - "winbat.ml" - "winbat_ast.ml" (syntax = "sexplib-syntax") - "winbat_compile.ml" - "winbat_format.ml" - "winbat_functions.ml" - "winbat_transform.ml" - ] - requires = ["core_kernel" "dlist" "sexplib-syntax"] - bundle = [ "batsh" ] -end - -begin program "batsh" - files = [ - "main.ml" - ] - requires = ["batsh-lib" "cmdliner"] -end - -begin program "test" - files = ["test.ml"] - test_dir = "tests" - test_asm = false - test_byte = false - requires = ["batsh-lib" "core" "oUnit" "threads"] - install = false -end - -begin syntax "sexplib-syntax" - install = false - requires = [ - "camlp4o" - "pa_sexp_conv.syntax" - ] -end - -(* sexplib syntax *) -begin - generated = true - dirname = ["%{sexplib_DST_DIR}%"] - begin library "pa_sexp_conv" - files = ["pa_sexp_conv.ml"] - requires = ["pa_type_conv"] - end - begin syntax "pa_sexp_conv.syntax" - requires = ["pa_sexp_conv"] - end - (* type_conv syntax *) - begin - generated = true - dirname = ["%{type_conv_DST_DIR}%"] - begin library "pa_type_conv" - is_before = ["pa_macro"] - requires = ["camlp4-pa-o" "camlp4-pa-op"] - files = ["pa_type_conv.ml"] - end - begin syntax "pa_type_conv.syntax" - requires = ["pa_type_conv"] - end - end -end - -begin library "threads" - installed = true - dirname = ["%{OCAMLLIB}%/threads"] - has_byte = false - byte += ["-custom"] -end diff --git a/src/batsh_ast.ml b/src/batsh_ast.ml deleted file mode 100644 index 3d0ceb8..0000000 --- a/src/batsh_ast.ml +++ /dev/null @@ -1,45 +0,0 @@ -open Core_kernel.Std - -type identifier = string - -and identifiers = identifier list - -and leftvalue = - | Identifier of identifier - | ListAccess of (leftvalue * expression) - -and expression = - | Bool of bool - | Float of float - | Int of int - | List of expressions - | String of string - | Leftvalue of leftvalue - | ArithUnary of (string * expression) - | ArithBinary of (string * expression * expression) - | Concat of (expression * expression) - | StrCompare of (string * expression * expression) - | Call of (identifier * expressions) - -and expressions = expression list - -and statement = - | Comment of string - | Block of statements - | Expression of expression - | Assignment of (leftvalue * expression) - | If of (expression * statement) - | IfElse of (expression * statement * statement) - | While of (expression * statement) - | Global of identifier - | Return of expression option - | Empty - -and statements = statement list - -and toplevel = - | Statement of statement - | Function of (identifier * identifiers * statements) - -and t = toplevel list -with sexp_of diff --git a/src/batsh_format.ml b/src/batsh_format.ml deleted file mode 100644 index 159e2ab..0000000 --- a/src/batsh_format.ml +++ /dev/null @@ -1,135 +0,0 @@ -open Core_kernel.Std -open Batsh_ast - -let rec print_lvalue (buf : Buffer.t) (lvalue: leftvalue) = - match lvalue with - | Identifier ident -> - Buffer.add_string buf ident - | ListAccess (lvalue, expr) -> - bprintf buf "%a[%a]" print_lvalue lvalue print_expression expr - -and print_expression (buf : Buffer.t) (expr: expression) = - match expr with - | Leftvalue lvalue -> print_lvalue buf lvalue - | Int number -> Buffer.add_string buf (string_of_int number) - | Float number -> Buffer.add_string buf (Float.to_string number) - | String str -> bprintf buf "\"%s\"" (Formatutil.escape str) - | Bool true -> Buffer.add_string buf "true" - | Bool false -> Buffer.add_string buf "false" - | ArithUnary (operator, expr) -> - bprintf buf "%s(%a)" operator print_expression expr - | ArithBinary binary | StrCompare binary -> - print_binary_expression buf binary - | Concat (left, right) -> - print_binary_expression buf ("++", left, right) - | Call (ident, exprs) -> - bprintf buf "%s(%a)" ident print_expressions exprs - | List exprs -> - bprintf buf "[%a]" print_expressions exprs - -and print_expressions (buf : Buffer.t) (exprs: expression list) = - Formatutil.print_separate_list buf exprs - ~f: print_expression ~separator: ", " - -and print_binary_expression - (buf : Buffer.t) - (operator, left, right) - = - bprintf buf "(%a %s %a)" - print_expression left operator print_expression right - -let rec print_statement (buf : Buffer.t) (stmt: statement) ~(indent: int) = - let () = match stmt with - | Block _ -> () - | _ -> - Formatutil.print_indent buf indent in - match stmt with - | Comment comment -> - bprintf buf "//%s" comment - | Block inner_stmts -> print_block_statement ~indent buf inner_stmts - | Expression expr -> - print_expression buf expr; - Buffer.add_string buf ";" - | Assignment (lvalue, expr) -> - bprintf buf "%a = %a;" print_lvalue lvalue print_expression expr - | If (expr, stmt) -> - print_if_statement buf expr stmt ~indent - | IfElse (expr, thenStmt, elseStmt) -> - print_if_else_statement buf expr thenStmt elseStmt ~indent - | While (expr, stmt) -> - print_while_statement buf expr stmt ~indent - | Global ident -> - bprintf buf "global %s;" ident - | Return (Some expr) -> - bprintf buf "return %a;" print_expression expr - | Return None -> - bprintf buf "return;" - | Empty -> () - -and print_statements = Formatutil.print_statements ~f: print_statement - -and print_block_statement - (buf : Buffer.t) - (inner_stmts : statements) - ~(indent : int) - = - let print_statements_indented = print_statements ~indent:(indent + 2) in - bprintf buf "{\n%a\n%a}" - print_statements_indented inner_stmts - Formatutil.print_indent indent - -and print_if_while_statement - (buf : Buffer.t) - (name : string) - (expr : expression) - (stmt : statement) - ~(indent : int) - = - bprintf buf "%s (%a) " name print_expression expr; - print_statement buf stmt ~indent - -and print_if_statement - (buf : Buffer.t) - (expr: expression) - (stmt: statement) - ~(indent: int) - = - print_if_while_statement buf "if" expr stmt ~indent - -and print_if_else_statement - (buf : Buffer.t) - (expr: expression) - (thenStmt: statement) - (elseStmt: statement) - ~(indent: int) - = - print_if_statement buf expr thenStmt ~indent; - Buffer.add_string buf " else "; - print_statement buf elseStmt ~indent - -and print_while_statement - (buf : Buffer.t) - (expr: expression) - (stmt: statement) - ~(indent: int) - = - print_if_while_statement buf "while" expr stmt ~indent - -let print_params (buf : Buffer.t) (params: identifiers) = - Formatutil.print_separate_list buf params ~f: Buffer.add_string ~separator: ", " - -let print_function (buf : Buffer.t) (name, params, stmts) = - bprintf buf "function %s (%a) {\n%a\n}" - name - print_params params - (print_statements ~indent: 2) stmts - -let print_toplevel (buf : Buffer.t) (topl: toplevel) ~indent = - match topl with - | Statement stmt -> - print_statement buf stmt ~indent - | Function func -> - print_function buf func - -let print_ast (buf : Buffer.t) (ast: t) = - Formatutil.print_statements buf ast ~f: print_toplevel ~indent: 0 diff --git a/src/errors.ml b/src/errors.ml deleted file mode 100644 index 9fdda3e..0000000 --- a/src/errors.ml +++ /dev/null @@ -1 +0,0 @@ -exception SemanticError of (string * string) diff --git a/src/errors.mli b/src/errors.mli deleted file mode 100644 index 9fdda3e..0000000 --- a/src/errors.mli +++ /dev/null @@ -1 +0,0 @@ -exception SemanticError of (string * string) diff --git a/src/formatutil.ml b/src/formatutil.ml deleted file mode 100644 index f9099d6..0000000 --- a/src/formatutil.ml +++ /dev/null @@ -1,41 +0,0 @@ -open Core_kernel.Std - -let print_indent (buf : Buffer.t) (indent : int) = - Buffer.add_string buf (String.make indent ' ') - -let print_statements - (buf : Buffer.t) - (stmts : 'a list) - ~(f : Buffer.t -> 'a -> indent:int -> unit) - ~(indent : int) = - let print_statement_indented buf stmt = f buf stmt ~indent in - let num_stmts = List.length stmts in - List.iteri stmts ~f: (fun i stmt -> - print_statement_indented buf stmt; - if i < num_stmts - 1 then - Buffer.add_string buf "\n" - ) - -let print_separate_list - (buf : Buffer.t) - (elements : 'a list) - ~(f : Buffer.t -> 'a -> unit) - ~(separator : string) = - let num_elements = List.length elements in - List.iteri elements ~f: (fun i element -> - f buf element; - if i < num_elements - 1 then - Buffer.add_string buf separator - ) - -let escaper = Staged.unstage ( - String.Escaping.escape_gen_exn - ~escapeworthy_map: [ - ('\n', 'n'); - ('\r', 'r'); - ('\"', '"')] - ~escape_char: '\\' - ) - -let escape (str : string) : string = - escaper str diff --git a/src/lexer.mll b/src/lexer.mll deleted file mode 100644 index fb88ab3..0000000 --- a/src/lexer.mll +++ /dev/null @@ -1,97 +0,0 @@ -{ -open Lexing -open Parser_yacc - -exception SyntaxError of string - -let next_line (lexbuf: Lexing.lexbuf) = - let pos = lexbuf.lex_curr_p in - lexbuf.lex_curr_p <- - { pos with pos_bol = lexbuf.lex_curr_pos; - pos_lnum = pos.pos_lnum + 1 - } - -} - -let int = '-'? ['0'-'9'] ['0'-'9']* - -let digit = ['0'-'9'] -let frac = '.' digit* -let exp = ['e' 'E'] ['-' '+']? digit+ -let float = digit* frac? exp? - -let white = [' ' '\t']+ -let newline = '\r' | '\n' | "\r\n" -let ident = ['a'-'z' 'A'-'Z' '_'] ['a'-'z' 'A'-'Z' '0'-'9' '_']* - -rule read = - parse - | white { read lexbuf } - | newline { next_line lexbuf; read lexbuf } - | int { INT (int_of_string (Lexing.lexeme lexbuf)) } - | float { FLOAT (float_of_string (Lexing.lexeme lexbuf)) } - | "true" { TRUE } - | "false" { FALSE } - | "if" { IF } - | "else" { ELSE } - | "while" { WHILE } - | "function" { FUNCTION } - | "global" { GLOBAL } - | "return" { RETURN } - | '=' { EQUAL } - | '"' { read_string (Buffer.create 17) lexbuf } - | '(' { LEFT_PAREN } - | ')' { RIGHT_PAREN } - | '{' { LEFT_BRACE } - | '}' { RIGHT_BRACE } - | '[' { LEFT_BRACK } - | ']' { RIGHT_BRACK } - | ';' { SEMICOLON } - | ',' { COMMA } - | '+' { PLUS } - | '-' { MINUS } - | '*' { MULTIPLY } - | '/' { DIVIDE } - | '%' { MODULO } - | "++" { CONCAT } - | '!' { NOT } - | "==" { SEQ } - | "!=" { SNE } - | "===" { AEQ } - | "!==" { ANE } - | '>' { GT } - | '<' { LT } - | ">=" { GE } - | "<=" { LE } - | "//" { read_line_comment (Buffer.create 17) lexbuf } - | ident { IDENTIFIER (Lexing.lexeme lexbuf) } - | eof { EOF } - | _ { raise (SyntaxError ( - "Unexpected char: " ^ Lexing.lexeme lexbuf)) } - -and read_string buf = - parse - | '"' { STRING (Buffer.contents buf) } - | '\\' '"' { Buffer.add_char buf '"'; read_string buf lexbuf } - | '\\' '\\' { Buffer.add_char buf '\\'; read_string buf lexbuf } - | '\\' 'b' { Buffer.add_char buf '\b'; read_string buf lexbuf } - | '\\' 'f' { Buffer.add_char buf '\012'; read_string buf lexbuf } - | '\\' 'n' { Buffer.add_char buf '\n'; read_string buf lexbuf } - | '\\' 'r' { Buffer.add_char buf '\r'; read_string buf lexbuf } - | '\\' 't' { Buffer.add_char buf '\t'; read_string buf lexbuf } - | [^ '"' '\\']+ - { Buffer.add_string buf (Lexing.lexeme lexbuf); - read_string buf lexbuf - } - | _ { raise (SyntaxError ("Illegal string character: " ^ Lexing.lexeme lexbuf)) } - | eof { raise (SyntaxError ("String is not terminated")) } - -and read_line_comment buf = - parse - | newline - | eof - { COMMENT (Buffer.contents buf) } - | _ - { Buffer.add_string buf (Lexing.lexeme lexbuf); - read_line_comment buf lexbuf - } diff --git a/src/main.ml b/src/main.ml deleted file mode 100644 index f364227..0000000 --- a/src/main.ml +++ /dev/null @@ -1,130 +0,0 @@ -open Core_kernel.Std -open Cmdliner - -(* Options common to all commands *) - -type output_type = Code | Ast | Symbols - -type copts = { - output_type : output_type; - output_file : string option -} - -let copts_sect = "COMMON OPTIONS" - -let copts_t = - let docs = copts_sect in - - let output_type = - let doc = "Print abstract syntax tree instead." in - let quiet = Ast, Arg.info ["ast"] ~docs ~doc in - - let doc = "Print symbol table instead." in - let verbose = Symbols, Arg.info ["symbols"] ~docs ~doc in - Arg.(last & vflag_all [Code] [quiet; verbose]) - in - - let output_file = - let doc = "Write output to $(docv)." in - let opts = ["o"; "output"] in - Arg.(value & opt (some string) None & info opts ~docs ~doc ~docv:"FILE") - in - let copts_cons output_type output_file = { output_type; output_file } in - Term.(pure copts_cons $ output_type $ output_file) - -let get_outx opts = - match opts.output_file with - | Some filename -> Out_channel.create filename - | None -> Out_channel.stdout - -let print_common opts ~batsh ~code ~ast = - let outx = get_outx opts in - match opts.output_type with - | Code -> - fprintf outx "%s\n" (Lazy.force code) - | Ast -> - fprintf outx "%a\n" Sexp.output_hum (Lazy.force ast) - | Symbols -> - let symtable_sexp = Symbol_table.sexp_of_t (Parser.symtable batsh) in - fprintf outx "%a\n" Sexp.output_hum symtable_sexp - -(* Commands *) - -let parse_with_error (filename : string) : Parser.t = - try - Parser.create_from_file filename - with - | Parser.ParseError msg -> - eprintf "%s\n" msg; - exit 1 - | Parser.SemanticError msg -> - eprintf "%s\n" msg; - exit 1 - -let bash = - let doc = "Compile $(docv) to Bash script." in - let t = - Arg.(required & pos 0 (some non_dir_file) None & info [] ~doc ~docv:"FILE") - in - let cmd opts (filename : string) = - let batsh = parse_with_error filename in - let bash = - try - Bash.compile batsh - with - | Errors.SemanticError (msg, context) -> - eprintf "%s\n%s\n" msg context; - exit 1 - in - let code = lazy (Bash.print bash) in - let ast = lazy (Bash.ast bash |> Bash_ast.sexp_of_t) in - print_common opts ~code ~ast ~batsh - in - Term.(pure cmd $ copts_t $ t), - Term.info "bash" ~doc:"Compile to Bash script." - -let winbat = - let doc = "Compile $(docv) to Windows Batch script." in - let t = - Arg.(required & pos 0 (some non_dir_file) None & info [] ~doc ~docv:"FILE") - in - let cmd opts (filename : string) = - let batsh = parse_with_error filename in - let winbat = - try - Winbat.compile batsh - with - | Errors.SemanticError (msg, context) -> - eprintf "%s\n%s\n" msg context; - exit 1 - in - let code = lazy (Winbat.print winbat) in - let ast = lazy (Winbat.ast winbat |> Winbat_ast.sexp_of_t) in - print_common opts ~code ~ast ~batsh - in - Term.(pure cmd $ copts_t $ t), - Term.info "winbat" ~doc:"Compile to Windows Batch script." - -let batsh = - let doc = "Format $(docv)." in - let t = - Arg.(required & pos 0 (some non_dir_file) None & info [] ~doc ~docv:"FILE") - in - let cmd opts (filename : string) = - let batsh = parse_with_error filename in - let code = lazy (Parser.prettify batsh) in - let ast = lazy (Parser.ast batsh |> Batsh_ast.sexp_of_t) in - print_common opts ~code ~ast ~batsh - in - Term.(pure cmd $ copts_t $ t), - Term.info "batsh" ~doc:"Format source file." - -let default_cmd = - let doc = Version.description in - Term.(ret (pure (fun _ -> `Help (`Plain, None)) $ (Term.pure ()) )), - Term.info "batsh" ~version:Version.version ~doc - -let () = - match Term.eval_choice default_cmd [bash; winbat; batsh] with - | `Error _ -> exit 1 - | _ -> () diff --git a/src/parser.ml b/src/parser.ml deleted file mode 100644 index a29ce58..0000000 --- a/src/parser.ml +++ /dev/null @@ -1,68 +0,0 @@ -open Core_kernel.Std - -type t = { - lex: Lexing.lexbuf; - ast: Batsh_ast.t; - symtable: Symbol_table.t; -} - -exception ParseError of string -exception SemanticError of string - -let parse (lexbuf : Lexing.lexbuf) : Batsh_ast.t = - let print_position () () = - let pos = lexbuf.Lexing.lex_curr_p in - sprintf "%s:%d:%d" - pos.Lexing.pos_fname - pos.Lexing.pos_lnum - (pos.Lexing.pos_cnum - pos.Lexing.pos_bol + 1) - in - try - Parser_yacc.program Lexer.read lexbuf - with - | Lexer.SyntaxError msg -> - let err = sprintf "%a: %s" print_position () msg in - raise (ParseError err) - | Parsing.Parse_error -> - let err = sprintf "%a: syntax error" print_position () in - raise (ParseError err) - -let create_from_lexbuf (lexbuf : Lexing.lexbuf) (filename: string) : t = - lexbuf.Lexing.lex_curr_p <- { - lexbuf.Lexing.lex_curr_p with Lexing.pos_fname = filename - }; - let ast = parse lexbuf in - let () = - try - Semantic_checker.check ast - with - | Semantic_checker.Error msg -> - raise (SemanticError (sprintf "Semantic error: %s" msg)) - in - let symtable = Symbol_table.create ast in - { lex = lexbuf; ast; symtable; } - -let create_from_channel (inx: in_channel) (filename: string) : t = - let lexbuf = Lexing.from_channel inx in - create_from_lexbuf lexbuf filename - -let create_from_file (filename : string) : t = - let inx = In_channel.create filename in - let batsh = create_from_channel inx filename in - In_channel.close inx; - batsh - -let create_from_string (source : string) : t = - let lexbuf = Lexing.from_string source in - create_from_lexbuf lexbuf "input" - -let prettify (batsh : t) : string = - let buf = Buffer.create 1024 in - Batsh_format.print_ast buf batsh.ast; - Buffer.contents buf - -let ast (batsh: t) : Batsh_ast.t = - batsh.ast - -let symtable (batsh: t) : Symbol_table.t = - batsh.symtable diff --git a/src/parser.mli b/src/parser.mli deleted file mode 100644 index 4851583..0000000 --- a/src/parser.mli +++ /dev/null @@ -1,11 +0,0 @@ -type t - -exception ParseError of string -exception SemanticError of string - -val create_from_file : string -> t -val create_from_channel : in_channel -> string -> t -val create_from_string : string -> t -val prettify : t -> string -val ast : t -> Batsh_ast.t -val symtable : t -> Symbol_table.t diff --git a/src/parser_yacc.mly b/src/parser_yacc.mly deleted file mode 100644 index 854afa3..0000000 --- a/src/parser_yacc.mly +++ /dev/null @@ -1,198 +0,0 @@ -%token INT -%token FLOAT -%token STRING -%token IDENTIFIER -%token COMMENT -%token TRUE -%token FALSE -%token IF -%token ELSE -%token WHILE -%token FUNCTION -%token GLOBAL -%token RETURN -%token EQUAL -%token LEFT_PAREN -%token RIGHT_PAREN -%token LEFT_BRACK -%token RIGHT_BRACK -%token LEFT_BRACE -%token RIGHT_BRACE -%token SEMICOLON -%token COMMA -%token PLUS -%token MINUS -%token MULTIPLY -%token DIVIDE -%token MODULO -%token CONCAT -%token NOT -%token SEQ -%token SNE -%token AEQ -%token ANE -%token GT -%token LT -%token GE -%token LE -%token EOF - -%nonassoc SEQ SNE AEQ ANE -%nonassoc GT LT GE LE -%left CONCAT -%nonassoc NOT -%left PLUS MINUS -%left MULTIPLY DIVIDE MODULO - -%nonassoc IF -%nonassoc ELSE - -%start program -%type program - -%% - -program: - toplevel_list; EOF; - { $1 } - ; - -toplevel: - | statement; - { Batsh_ast.Statement $1 } - | FUNCTION; IDENTIFIER; LEFT_PAREN; - identifier_list; RIGHT_PAREN; - LEFT_BRACE; statement_list; RIGHT_BRACE; - { Batsh_ast.Function ($2, $4, $7) } - -toplevel_list: - | { [] } - | toplevel; toplevel_list; - { $1 :: $2 } - ; - -statement: - | SEMICOLON; - { Batsh_ast.Empty } - | COMMENT; - { Batsh_ast.Comment $1 } - | expression; SEMICOLON; - { Batsh_ast.Expression $1 } - | LEFT_BRACE; statement_list; RIGHT_BRACE; - { Batsh_ast.Block $2 } - | leftvalue; EQUAL; expression; SEMICOLON; - { Batsh_ast.Assignment ($1, $3) } - | if_statement; - { $1 } - | loop_statement; - { $1 } - | GLOBAL IDENTIFIER; SEMICOLON; - { Batsh_ast.Global $2 } - | RETURN expression; SEMICOLON; - { Batsh_ast.Return (Some $2)} - | RETURN SEMICOLON; - { Batsh_ast.Return None} - ; - -statement_list: - | { [] } - | statement; statement_list; - { $1 :: $2 } - ; - -if_statement: - | IF; LEFT_PAREN; expression; RIGHT_PAREN; statement; - %prec IF; - { Batsh_ast.If ($3, $5) } - | IF; LEFT_PAREN; expression; RIGHT_PAREN; statement; ELSE; statement; - { Batsh_ast.IfElse ($3, $5, $7) } - ; - -loop_statement: - | WHILE; LEFT_PAREN; expression; RIGHT_PAREN; statement; - { Batsh_ast.While ($3, $5) } - ; - -expression: - | leftvalue - { Batsh_ast.Leftvalue $1 } - | STRING - { Batsh_ast.String $1 } - | INT - { Batsh_ast.Int $1 } - | FLOAT - { Batsh_ast.Float $1 } - | TRUE - { Batsh_ast.Bool true } - | FALSE - { Batsh_ast.Bool false } - | LEFT_BRACK; expression_list; RIGHT_BRACK - { Batsh_ast.List $2 } - | unary_expression; - { $1 } - | binary_expression; - { $1 } - | LEFT_PAREN; expression; RIGHT_PAREN; - { $2 } - | IDENTIFIER; LEFT_PAREN; expression_list; RIGHT_PAREN; - { Batsh_ast.Call ($1, $3) } - ; - -expression_list: - | { [] } - | expression; - { [$1] } - | expression; COMMA; expression_list; - { $1 :: $3 } - ; - -identifier_list: - | { [] } - | IDENTIFIER; - { [$1] } - | IDENTIFIER; COMMA; identifier_list; - { $1 :: $3 } - ; - -leftvalue: - | IDENTIFIER; - { Batsh_ast.Identifier $1 } - | leftvalue; LEFT_BRACK; expression; RIGHT_BRACK; - { Batsh_ast.ListAccess ($1, $3) } - ; - -unary_expression: - | NOT; expression; - { Batsh_ast.ArithUnary ("!", $2) } - ; - -binary_expression: - | expression; PLUS; expression; - { Batsh_ast.ArithBinary ("+", $1, $3) } - | expression; MINUS; expression; - { Batsh_ast.ArithBinary ("-", $1, $3) } - | expression; MULTIPLY; expression; - { Batsh_ast.ArithBinary ("*", $1, $3) } - | expression; DIVIDE; expression; - { Batsh_ast.ArithBinary ("/", $1, $3) } - | expression; MODULO; expression; - { Batsh_ast.ArithBinary ("%", $1, $3) } - | expression; AEQ; expression; - { Batsh_ast.ArithBinary ("===", $1, $3) } - | expression; ANE; expression; - { Batsh_ast.ArithBinary ("!==", $1, $3) } - | expression; GT; expression; - { Batsh_ast.ArithBinary (">", $1, $3) } - | expression; LT; expression; - { Batsh_ast.ArithBinary ("<", $1, $3) } - | expression; GE; expression; - { Batsh_ast.ArithBinary (">=", $1, $3) } - | expression; LE; expression; - { Batsh_ast.ArithBinary ("<=", $1, $3) } - | expression; CONCAT; expression; - { Batsh_ast.Concat ($1, $3) } - | expression; SEQ; expression; - { Batsh_ast.StrCompare ("==", $1, $3) } - | expression; SNE; expression; - { Batsh_ast.StrCompare ("!=", $1, $3) } - ; diff --git a/src/semantic_checker.ml b/src/semantic_checker.ml deleted file mode 100644 index f7c42e5..0000000 --- a/src/semantic_checker.ml +++ /dev/null @@ -1,29 +0,0 @@ -open Core_kernel.Std -open Batsh_ast - -exception Error of string - -let check_function_statement (stmt : statement) = - match stmt with - | Return (Some List _) -> - raise (Error "list can not be used as a return value") - | _ -> - () - -let check_function (func : (identifier * identifiers * statements)) = - let name, params, stmts = func in - List.iter stmts ~f: check_function_statement - -let check_toplevel (topl : toplevel) = - match topl with - | Statement (Global _) -> - raise (Error "qualifier 'global' must be used in a function") - | Statement (Return _) -> - raise (Error "statement 'return' must be used in a function") - | Statement _ -> - () - | Function func -> - check_function func - -let check (ast : t) : unit = - List.iter ast ~f: check_toplevel diff --git a/src/symbol_table.ml b/src/symbol_table.ml deleted file mode 100644 index 46d2765..0000000 --- a/src/symbol_table.ml +++ /dev/null @@ -1,167 +0,0 @@ -open Core_kernel.Std -open Batsh_ast - -type variable_entry = { - name : string; - global : bool; -} -with sexp_of - -type variable_table = (string, variable_entry) Hashtbl.t - -let sexp_of_variable_table (vtable : variable_table) : Sexp.t = - Sexp.List (Hashtbl.fold vtable ~init: [] - ~f: (fun ~key ~data acc -> - let item = (sexp_of_variable_entry data) in - item :: acc - ) - ) - -type function_entry = - | Declaration - | Defination of variable_table -with sexp_of - -type t = { - functions : (string, function_entry) Hashtbl.t; - globals : variable_table; -} -with sexp_of - -module Scope = struct - type t = - | GlobalScope of variable_table - | FunctionScope of (string * variable_table) - with sexp_of - - let is_function (scope : t) : bool = - match scope with - | GlobalScope _ -> false - | FunctionScope _ -> true - - let variables (scope : t) : variable_table = - match scope with - | GlobalScope variables -> variables - | FunctionScope (_, variables) -> variables - - let find_variable - (scope: t) - ~(name: string) - : variable_entry option = - Hashtbl.find (variables scope) name - - let is_global_variable - (scope : t) - ~(name : string) - : bool = - match scope with - | GlobalScope _ -> true - | FunctionScope (_, variable_table) -> - match Hashtbl.find variable_table name with - | None -> true (* if variable is not found, consider it as external *) - | Some variable -> variable.global - - let fold - (scope: t) - ~(init: 'a) - ~(f: string -> bool -> 'a -> 'a) = - let vtable = variables scope in - Hashtbl.fold vtable ~init - ~f: (fun ~key ~data acc -> f data.name data.global acc) - - let add_temporary_variable - (scope: t) - : identifier = - let rec find_available_name (num : int) : string = - let name = "_" ^ (Int.to_string num) in - match find_variable scope ~name with - | None -> - (* Add to symbol table *) - let variables = variables scope in - Hashtbl.add_exn variables ~key: name ~data: {name; global = false}; - name - | Some _ -> - (* Duplicated, try again *) - find_available_name (num + 1) - in - find_available_name 0 -end - -let process_identifier - (scope: variable_table) - (ident: identifier) - ~(global: bool) = - Hashtbl.change scope ident (fun original -> - let entry = Some { - name = ident; - global = global; - } - in - match original with - | None -> entry - | Some existing -> - if global && not existing.global then - entry - else - original - ) - -let rec process_leftvalue - (scope: variable_table) - (lvalue: leftvalue) - ~(global: bool) = - match lvalue with - | Identifier ident -> - process_identifier scope ident ~global - | ListAccess (lvalue, _) -> - process_leftvalue scope lvalue ~global - -let process_statement - (scope: variable_table) - (stmt: statement) = - match stmt with - | Assignment (lvalue, _) -> process_leftvalue scope lvalue ~global: false - | Global ident -> process_identifier scope ident ~global: true - | _ -> () - -let process_function - functions - (name, params, stmts) = - match Hashtbl.find functions name with - | Some _ -> () (* TODO duplicate *) - | None -> - let variables = Hashtbl.create ~hashable: String.hashable () in - Hashtbl.change functions name (fun original -> - (* TODO declaration *) - Some (Defination variables) - ); - List.iter stmts ~f: (process_statement variables); - List.iter params ~f: (process_identifier variables ~global: false) - -let process_toplevel (symtable: t) (topl: toplevel) = - match topl with - | Statement stmt -> process_statement symtable.globals stmt - | Function func -> process_function symtable.functions func - -let create (ast: Batsh_ast.t) :t = - let symtable = { - functions = Hashtbl.create ~hashable: String.hashable (); - globals = Hashtbl.create ~hashable: String.hashable () - } in - List.iter ast ~f: (process_toplevel symtable); - symtable - -let scope (symtable: t) (name: string) : Scope.t = - let variables = match Hashtbl.find_exn symtable.functions name with - | Declaration -> failwith "No such function" - | Defination variables -> variables - in - Scope.FunctionScope (name, variables) - -let global_scope (symtable: t) : Scope.t = - Scope.GlobalScope symtable.globals - -let is_function (symtable : t) (name : string) : bool = - match Hashtbl.find symtable.functions name with - | Some _ -> true - | None -> false diff --git a/src/symbol_table.mli b/src/symbol_table.mli deleted file mode 100644 index 37d7290..0000000 --- a/src/symbol_table.mli +++ /dev/null @@ -1,17 +0,0 @@ -open Core_kernel.Std - -type t - -module Scope : sig - type t - val is_function : t -> bool - val is_global_variable : t -> name: string -> bool - val add_temporary_variable : t -> Batsh_ast.identifier - val fold : t -> init: 'a -> f: (string -> bool -> 'a -> 'a) -> 'a -end - -val create : Batsh_ast.t -> t -val scope : t -> string -> Scope.t -val global_scope : t -> Scope.t -val sexp_of_t : t -> Sexp.t -val is_function : t -> string -> bool diff --git a/src/test.ml b/src/test.ml deleted file mode 100644 index bfdedb2..0000000 --- a/src/test.ml +++ /dev/null @@ -1,96 +0,0 @@ -open Core.Std -open Unix.Process_channels -open OUnit - -let drop_carrage_return str = - let buffer = Buffer.create (String.length str) in - String.iter str ~f:(fun ch -> - if ch <> '\r' then - Buffer.add_char buffer ch - ); - Buffer.contents buffer - -let test_result expected output exit_status = - let exit_message = Unix.Exit_or_signal.to_string_hum exit_status in - assert_equal "exited normally" exit_message ~printer: Fn.id; - assert_equal expected output ~printer: Fn.id - -let test_bash name batsh expected = - let bash = Bash.compile batsh in - let code = (Bash.print bash) ^ "\n" in - (* Code *) - let inx = In_channel.create ("tests/bash/" ^ name ^ ".sh") in - let code_expected = In_channel.input_all inx in - In_channel.close inx; - assert_equal code_expected code ~printer: Fn.id; - (* Run result *) - let stdout, stdin = Unix.open_process "bash" in - Out_channel.output_string stdin code; - Out_channel.close stdin; - let output = In_channel.input_all stdout in - let exit_status = Unix.close_process (stdout, stdin) in - test_result expected output exit_status - -let test_winbat name batsh expected = - let winbat = Winbat.compile batsh in - let code = (Winbat.print winbat) ^ "\n" in - (* Code *) - let inx = In_channel.create ("tests/batch/" ^ name ^ ".bat") in - let code_expected = In_channel.input_all inx in - In_channel.close inx; - assert_equal code_expected code ~printer: Fn.id; - (* Run result *) - let filename = Filename.temp_file "batsh" ".bat" in - let outx = Out_channel.create filename in - Out_channel.output_string outx code; - Out_channel.close outx; - - let cmd = "wine cmd /c " ^ filename in - let channels = Unix.open_process_full cmd ~env:[||] in - let output_raw = In_channel.input_all channels.stdout in - let output = drop_carrage_return output_raw in - let exit_status = Unix.close_process_full channels in - test_result expected output exit_status - -let get_expected name = - let answer_filename = "tests/output/" ^ name ^ ".txt" in - let inx = In_channel.create answer_filename in - let expected = In_channel.input_all inx in - In_channel.close inx; - expected - -let test name func _ = - let expected = get_expected name in - let filename = "tests/" ^ name ^ ".batsh" in - let batsh = Parser.create_from_file filename in - func name batsh expected - -let test_cases = "Batsh Unit Tests" >::: [ - "[Bash]Comment" >:: test "comment" test_bash; - "[Bash]Block" >:: test "block" test_bash; - "[Bash]Arith" >:: test "arith" test_bash; - "[Bash]Assignment" >:: test "assignment" test_bash; - "[Bash]Array" >:: test "array" test_bash; - "[Bash]String" >:: test "string" test_bash; - "[Bash]If" >:: test "if" test_bash; - "[Bash]While" >:: test "while" test_bash; - "[Bash]Function" >:: test "function" test_bash; - "[Bash]Recursion" >:: test "recursion" test_bash; - "[Bash]Command" >:: test "command" test_bash; - "[Bash]Exists" >:: test "exists" test_bash; - "[Winbat]Comment" >:: test "comment" test_winbat; - "[Winbat]Block" >:: test "block" test_winbat; - "[Winbat]Arith" >:: test "arith" test_winbat; - "[Winbat]Assignment" >:: test "assignment" test_winbat; - (* "[Winbat]Array" >:: test "array" test_winbat; *) - "[Winbat]String" >:: test "string" test_winbat; - "[Winbat]If" >:: test "if" test_winbat; - "[Winbat]While" >:: test "while" test_winbat; - "[Winbat]Function" >:: test "function" test_winbat; - "[Winbat]Recursion" >:: test "recursion" test_winbat; - "[Winbat]Command" >:: test "command" test_winbat; - "[Winbat]Exists" >:: test "exists" test_winbat; - ] - -let _ = - run_test_tt_main test_cases diff --git a/src/winbat.ml b/src/winbat.ml deleted file mode 100644 index 3a8411e..0000000 --- a/src/winbat.ml +++ /dev/null @@ -1,21 +0,0 @@ -type t = { - batsh : Parser.t; - batch_ast : Winbat_ast.t; - batch_ast_expanded : Winbat_ast.t; -} - -let compile (batsh : Parser.t) : t = - let batch_ast = Winbat_compile.compile batsh in - let batch_ast_expanded = Winbat_functions.expand batch_ast in - {batsh; batch_ast; batch_ast_expanded} - -let print (batch : t) : string = - let buf = Buffer.create 1024 in - Winbat_format.print buf batch.batch_ast_expanded; - Buffer.contents buf - -let ast ?(expand_functions=true) (winbat : t) : Winbat_ast.t = - if expand_functions then - winbat.batch_ast_expanded - else - winbat.batch_ast diff --git a/src/winbat.mli b/src/winbat.mli deleted file mode 100644 index 383e9e3..0000000 --- a/src/winbat.mli +++ /dev/null @@ -1,5 +0,0 @@ -type t - -val compile : Parser.t -> t -val print : t -> string -val ast : ?expand_functions:bool -> t -> Winbat_ast.t diff --git a/src/winbat_ast.ml b/src/winbat_ast.ml deleted file mode 100644 index 8ab3b60..0000000 --- a/src/winbat_ast.ml +++ /dev/null @@ -1,61 +0,0 @@ -open Core_kernel.Std - -type identifier = string - -and identifiers = identifier list - -and label = string - -and varint = [ - | `Var of leftvalue - | `Int of int -] - -and leftvalue = [ - | `Identifier of identifier - | `ListAccess of (leftvalue * varint) -] - -and arithmetic = [ - | `Var of leftvalue - | `Int of int - | `ArithUnary of (string * arithmetic) - | `ArithBinary of (string * arithmetic * arithmetic) -] - -and varstring = [ - | `Var of leftvalue - | `Str of string - | `Rawstr of string -] - -and varstrings = varstring list - -and comparison = [ - | `UniCompare of (string * varstrings) - | `StrCompare of (string * varstrings * varstrings) - | `TestCompare of (string * varstrings) -] - -and parameter = varstrings - -and parameters = parameter list - -and statement = [ - | `Comment of string - | `Raw of string - | `Label of label - | `Goto of label - | `Assignment of (leftvalue * varstrings) - | `ArithAssign of (leftvalue * arithmetic) - | `Call of (varstrings * parameters) - | `Output of (leftvalue * varstrings * parameters) - | `If of (comparison * statements) - | `IfElse of (comparison * statements * statements) - | `Empty -] - -and statements = statement list - -and t = statements -with sexp_of diff --git a/src/winbat_compile.ml b/src/winbat_compile.ml deleted file mode 100644 index ec59733..0000000 --- a/src/winbat_compile.ml +++ /dev/null @@ -1,544 +0,0 @@ -open Core_kernel.Std -open Batsh_ast -open Winbat_ast - -let rec compile_leftvalue - (lvalue: Batsh_ast.leftvalue) - ~(symtable: Symbol_table.t) - ~(scope: Symbol_table.Scope.t) - : leftvalue = - match lvalue with - | Identifier ident -> - `Identifier ident - | ListAccess (lvalue, index) -> - let lvalue = compile_leftvalue lvalue ~symtable ~scope in - let index = compile_expression_to_varint index ~symtable ~scope in - `ListAccess (lvalue, index) - -and compile_expression_to_varint - (expr : Batsh_ast.expression) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : varint = - match expr with - | Leftvalue lvalue -> - `Var (compile_leftvalue lvalue ~symtable ~scope) - | Int num -> - `Int num - | _ -> - raise (Errors.SemanticError - ("Index should be either var or int", - expr |> Batsh_ast.sexp_of_expression |> Sexp.to_string - ) - ) - -let rec compile_expression_to_arith - (expr : Batsh_ast.expression) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : arithmetic = - match expr with - | Bool false -> - `Int 0 - | Bool true -> - `Int 1 - | Int num -> - `Int num - | Leftvalue lvalue -> - `Var (compile_leftvalue lvalue ~symtable ~scope) - | ArithUnary (operator, expr) -> - `ArithUnary (operator, compile_expression_to_arith expr ~symtable ~scope) - | ArithBinary (operator, left, right) -> - `ArithBinary (operator, - compile_expression_to_arith left ~symtable ~scope, - compile_expression_to_arith right ~symtable ~scope) - | String _ - | Float _ - | List _ - | Concat _ - | StrCompare _ - | Call _ -> - Sexp.output_hum stderr (Batsh_ast.sexp_of_expression expr); - failwith "Can not be here" - -let compile_expression - (expr : Batsh_ast.expression) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : varstrings = - let rec compile_expression_impl - (expr : Batsh_ast.expression) - : varstring Dlist.t = - match expr with - | Bool false -> - Dlist.of_list [`Str "0"] - | Bool true -> - Dlist.of_list [`Str "1"] - | Int num -> - Dlist.of_list [`Str (string_of_int num)] - | Float num -> - Dlist.of_list [`Str (Float.to_string num)] - | String str -> - Dlist.of_list [`Str str] - | Leftvalue lvalue -> - Dlist.of_list [`Var (compile_leftvalue lvalue ~symtable ~scope)] - | Concat (left, right) -> - let left = compile_expression_impl left in - let right = compile_expression_impl right in - Dlist.append left right - | List _ - | ArithUnary _ - | ArithBinary _ - | StrCompare _ - | Call _ -> - Sexp.output_hum stderr (Batsh_ast.sexp_of_expression expr); - failwith "Bug: Must have been split into assignments." - in - Dlist.to_list (compile_expression_impl expr) - -let compile_expressions_to_arguments - (exprs : Batsh_ast.expressions) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : parameters = - List.map exprs ~f: (compile_expression ~symtable ~scope) - -let compile_expression_to_comparison - (expr : Batsh_ast.expression) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : comparison = - match expr with - | ArithUnary (operator, sub_expr) -> - let sub_expr = compile_expression sub_expr ~symtable ~scope in - `UniCompare (operator, sub_expr) - | StrCompare (operator, left, right) - | ArithBinary (operator, left, right) -> - let left = compile_expression left ~symtable ~scope in - let right = compile_expression right ~symtable ~scope in - `StrCompare (operator, left, right) - | Leftvalue lvalue -> - let lvalue = `Var (compile_leftvalue lvalue ~symtable ~scope) in - `StrCompare ("==", [lvalue], [`Str "1"]) - | Bool true | Int 1 -> - `UniCompare ("", [`Str "1"]) - | Bool false | Int _ -> - `UniCompare ("!", [`Str "1"]) - | Call ("exists", (sub_expr :: _)) -> - let clause = compile_expression sub_expr ~symtable ~scope in - `TestCompare ("exist", clause) - | _ -> - raise (Errors.SemanticError - ("Expression can not compile to comparison", - expr |> Batsh_ast.sexp_of_expression |> Sexp.to_string - ) - ) - -let compile_call - (ident, exprs) - ~(return_value : leftvalue option) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : statements = - let args = compile_expressions_to_arguments exprs ~symtable ~scope in - if Symbol_table.is_function symtable ident then - (* function call *) - let frame_pointer_assign, frame_pointer = - if Symbol_table.Scope.is_function scope then - (* add frame pointer as surffix to local variables *) - (* increase frame pointer %~2 by 1 *) - let frame_pointer = `Identifier ( - Symbol_table.Scope.add_temporary_variable scope) - in - [`ArithAssign ( - frame_pointer, - `ArithBinary ("+", `Int 1, `Var (`Identifier "%~2")) - ) - ], `Var (frame_pointer) - else - (* call from toplevel *) - [], `Str "0" - in - let retval = Symbol_table.Scope.add_temporary_variable scope in - let surffix = - if Symbol_table.Scope.is_function scope then - (* call from function scope *) - "_%~2" - else - (* call from toplevel *) - "" - in - let surffixed_retval = `Rawstr (retval ^ surffix) in - let stringified_args = List.map args ~f:(fun arg -> - match arg with - | [`Var (`Identifier ident)] -> - [`Rawstr (ident ^ surffix)] - | _ -> - Sexp.output_hum stderr (Winbat_ast.sexp_of_parameter arg); - failwith "Argument should have been converted to variable." - ) - in - let prefixed_args = [ - [surffixed_retval]; (* return value *) - [frame_pointer]; (* frame pointer *) - ] @ stringified_args in - let call_stmt = `Call ([`Str ("call :" ^ ident)], prefixed_args) in - let stmts = frame_pointer_assign @ [call_stmt] in - let stmts = - match return_value with - | Some lvalue -> - (* Assign return value *) - stmts @ [`Assignment (lvalue, [`Var (`Identifier retval)])] - | None -> - (* Print out return value *) - stmts @ [`Call ([`Str "print"], [[`Var (`Identifier retval)]])] - in - stmts - else - match ident with - | "exists" -> - let params_1 params = - match params with - | param :: _ -> param - | _ -> failwith ("exists must have only 1 parameter.") - in - let arg = compile_expression (params_1 exprs) ~symtable ~scope in - let cond = `TestCompare ("exist", arg) in - let stmts = - match return_value with - | Some lvalue -> - let true_stmt = [`ArithAssign (lvalue, `Int 1)] in - let false_stmt = [`ArithAssign (lvalue, `Int 0)] in - [`IfElse (cond, true_stmt, false_stmt)] - | None -> - [`IfElse (cond, [], [])] - in - stmts - | _ -> - (* external command *) - let stmts = - match return_value with - | Some lvalue -> - [`Output (lvalue, [`Str ident], args)] - | None -> - [`Call ([`Str ident], args)] - in - stmts - -let rec compile_expression_statement - (expr : Batsh_ast.expression) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : statements = - match expr with - | Call call -> - (* Call discarding return value *) - compile_call call ~return_value:None ~symtable ~scope - | Leftvalue _ -> - [] (* No side effect *) - | _ -> - Sexp.output_hum stderr (Batsh_ast.sexp_of_expression expr); - assert false (* TODO *) - -let compile_arith_assignment - (lvalue : Batsh_ast.leftvalue) - (expr : Batsh_ast.expression) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : statements = - match expr with - | ArithBinary ("===", _, _) - | ArithBinary ("!==", _, _) - | ArithBinary (">", _, _) - | ArithBinary ("<", _, _) - | ArithBinary (">=", _, _) - | ArithBinary ("<=", _, _) - | ArithUnary ("!", _) -> - let cond = compile_expression_to_comparison expr ~symtable ~scope in - let lvalue = compile_leftvalue lvalue ~symtable ~scope in - let true_stmt = [`ArithAssign (lvalue, `Int 1)] in - let false_stmt = [`ArithAssign (lvalue, `Int 0)] in - [`IfElse (cond, true_stmt, false_stmt)] - | Bool _ - | Int _ - | Float _ - | ArithUnary _ - | ArithBinary _ -> - let lvalue = compile_leftvalue lvalue ~symtable ~scope in - let arith = compile_expression_to_arith expr ~symtable ~scope in - [`ArithAssign (lvalue, arith)] - | _ -> - Sexp.output_hum stderr (Batsh_ast.sexp_of_leftvalue lvalue); - Sexp.output_hum stderr (Batsh_ast.sexp_of_expression expr); - failwith "Can not reach here." - -let rec compile_statement - (stmt : Batsh_ast.statement) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : statements = - match stmt with - | Comment comment -> - [`Comment comment] - | Block stmts -> - compile_statements stmts ~symtable ~scope - | Expression expr -> - compile_expression_statement expr ~symtable ~scope - | Assignment (lvalue, expr) -> - compile_assignment lvalue expr ~symtable ~scope - | If (expr, stmt) -> - [`If (compile_expression_to_comparison expr ~symtable ~scope, - compile_statement stmt ~symtable ~scope)] - | IfElse (expr, then_stmt, else_stmt) -> - [`IfElse (compile_expression_to_comparison expr ~symtable ~scope, - compile_statement then_stmt ~symtable ~scope, - compile_statement else_stmt ~symtable ~scope)] - | While (expr, stmt) -> - let condition = compile_expression_to_comparison expr ~symtable ~scope in - let body = compile_statement stmt ~symtable ~scope in - let label_surfix = Symbol_table.Scope.add_temporary_variable - (Symbol_table.global_scope symtable) - in - let label = sprintf "WHILE%s" label_surfix in - [ - `Label label; - `If (condition, body @ [`Goto label]); - ] - | Return (Some expr) -> - [ - `Assignment (`Identifier "%~1", compile_expression expr ~symtable ~scope); - `Goto ":EOF" - ] - | Return None -> - [`Goto ":EOF"] - | Global _ - | Empty -> - [] - -and compile_assignment - (lvalue : Batsh_ast.leftvalue) - (expr : Batsh_ast.expression) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : statements = - match expr with - | String _ - | Concat _ - | Leftvalue _ -> - let lvalue = compile_leftvalue lvalue ~symtable ~scope in - [`Assignment (lvalue, compile_expression expr ~symtable ~scope)] - | Bool _ - | Int _ - | Float _ - | ArithUnary _ - | ArithBinary _ -> - compile_arith_assignment lvalue expr ~symtable ~scope - | List exprs -> - List.concat (List.mapi exprs ~f: (fun i expr -> - compile_assignment (ListAccess (lvalue, (Int i))) expr ~symtable ~scope - )) - | Call call -> - (* Call obtaining return value *) - let lvalue = compile_leftvalue lvalue ~symtable ~scope in - compile_call call ~return_value:(Some lvalue) ~symtable ~scope - | StrCompare _ -> - let comp = compile_expression_to_comparison expr ~symtable ~scope in - let lvalue = compile_leftvalue lvalue ~symtable ~scope in - [`IfElse ( - comp, - [`ArithAssign (lvalue, `Int 1)], - [`ArithAssign (lvalue, `Int 0)] - ) - ] - -and compile_statements - (stmts: Batsh_ast.statements) - ~(symtable: Symbol_table.t) - ~(scope: Symbol_table.Scope.t) - : statements = - Dlist.to_list ( - List.fold stmts ~init: (Dlist.empty ()) ~f: (fun acc stmt -> - let stmts = compile_statement stmt ~symtable ~scope in - Dlist.append acc (Dlist.of_list stmts) - ) - ) - -(* Function variable, call, return replacement *) - -let rec compile_function_leftvalue - (lvalue : leftvalue) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : leftvalue = - match lvalue with - | `Identifier ident -> - if Symbol_table.Scope.is_global_variable scope ~name: ident then - lvalue - else - (* Add surfix _%~2 to local variable *) - `ListAccess (lvalue, `Var (`Identifier "%~2")) - | `ListAccess (lvalue, index) -> - `ListAccess (compile_function_leftvalue lvalue ~symtable ~scope, index) - -let compile_function_varstring - (var : varstring) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : varstring = - match var with - | `Var lvalue -> - `Var (compile_function_leftvalue lvalue ~symtable ~scope) - | `Str _ | `Rawstr _ -> - var - -let compile_function_varstrings - (vars : varstrings) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : varstrings = - List.map vars ~f: (compile_function_varstring ~symtable ~scope) - -let compile_function_parameters - (params : parameters) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : parameters = - List.map params ~f: (compile_function_varstrings ~symtable ~scope) - -let rec compile_function_arithmetic - (arith : arithmetic) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : arithmetic = - match arith with - | `Var lvalue -> - `Var (compile_function_leftvalue lvalue ~symtable ~scope) - | `Int _ -> - arith - | `ArithUnary (operator, arith) -> - `ArithUnary (operator, compile_function_arithmetic arith ~symtable ~scope) - | `ArithBinary (operator, left, right) -> - `ArithBinary (operator, - compile_function_arithmetic left ~symtable ~scope, - compile_function_arithmetic right ~symtable ~scope) - -let compile_function_comparison - (cond : comparison) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : comparison = - match cond with - | `TestCompare (operator, expr) -> - `TestCompare (operator, - compile_function_varstrings expr ~symtable ~scope) - | `UniCompare (operator, expr) -> - `UniCompare (operator, - compile_function_varstrings expr ~symtable ~scope) - | `StrCompare (operator, left, right) -> - `StrCompare (operator, - compile_function_varstrings left ~symtable ~scope, - compile_function_varstrings right ~symtable ~scope) - -let rec compile_function_statement - (stmt : statement) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : statement = - match stmt with - | `Comment _ | `Raw _ | `Label _ | `Goto _ | `Empty -> - stmt - | `Assignment (lvalue, vars) -> - `Assignment (compile_function_leftvalue lvalue ~symtable ~scope, - compile_function_varstrings vars ~symtable ~scope) - | `ArithAssign (lvalue, arith) -> - `ArithAssign (compile_function_leftvalue lvalue ~symtable ~scope, - compile_function_arithmetic arith ~symtable ~scope) - | `Call (name, params) -> - `Call (compile_function_varstrings name ~symtable ~scope, - compile_function_parameters params ~symtable ~scope) - | `Output (lvalue, name, params) -> - `Output ( - compile_function_leftvalue lvalue ~symtable ~scope, - compile_function_varstrings name ~symtable ~scope, - compile_function_parameters params ~symtable ~scope) - | `If (cond, stmts) -> - `If (compile_function_comparison cond ~symtable ~scope, - compile_function_statements stmts ~symtable ~scope) - | `IfElse (cond, then_stmts, else_stmts) -> - `IfElse (compile_function_comparison cond ~symtable ~scope, - compile_function_statements then_stmts ~symtable ~scope, - compile_function_statements else_stmts ~symtable ~scope) - -and compile_function_statements - (stmts : statements) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : statements = - List.map stmts ~f: (compile_function_statement ~symtable ~scope) - -let compile_function - (name, params, stmts) - ~(symtable : Symbol_table.t) - : statements = - let scope = Symbol_table.scope symtable name in - let body = compile_statements stmts ~symtable ~scope in - let replaced_body = compile_function_statements body ~symtable ~scope in - let params_assignments = List.mapi params ~f: (fun i param -> - (* Add frame pointer surfix to every paramemeter *) - let lvalue = `ListAccess (`Identifier param, `Var (`Identifier "%~2")) in - let param_var = (sprintf "!%%~%d!" (i + 3)) in - `Assignment (lvalue, [`Rawstr param_var]) - ) - in - (`Empty - :: (`Goto ":EOF") - :: (`Label name) - :: params_assignments) - @ replaced_body - -let compile_toplevel - ~(symtable : Symbol_table.t) - (topl: Batsh_ast.toplevel) - : statements = - match topl with - | Statement stmt -> - compile_statement stmt ~symtable - ~scope: (Symbol_table.global_scope symtable) - | Function func -> - compile_function func ~symtable - -let sort_functions (topls : Batsh_ast.t) : Batsh_ast.t = - let is_function topl : bool = - match topl with - | Function _ -> true - | Statement _ -> false - in - List.stable_sort topls ~cmp: (fun a b -> - let func_a = is_function a in - let func_b = is_function b in - match (func_a, func_b) with - | (true, true) -> 0 - | (true, false) -> 1 - | (false, true) -> -1 - | (false, false) -> 0 - ) - -let compile (batsh: Parser.t) : t = - let ast = Parser.ast batsh in - let symtable = Parser.symtable batsh in - let transformed_ast = Winbat_transform.split ast ~symtable in - let sorted_ast = sort_functions transformed_ast in - let stmts = Dlist.to_list ( - List.fold_left sorted_ast - ~init: (Dlist.empty ()) - ~f: (fun acc topl -> - let stmts = compile_toplevel topl ~symtable in - Dlist.append acc (Dlist.of_list stmts) - ) - ) - in - (`Raw "@echo off") - :: (`Raw "setlocal EnableDelayedExpansion") - :: (`Raw "setlocal EnableExtensions") - :: (`Empty) - :: stmts diff --git a/src/winbat_format.ml b/src/winbat_format.ml deleted file mode 100644 index bdee97c..0000000 --- a/src/winbat_format.ml +++ /dev/null @@ -1,194 +0,0 @@ -open Core_kernel.Std -open Winbat_ast - -let escape (str : string) : string = - let buffer = Buffer.create (String.length str) in - let exclamation = match String.index str '!' with - | None -> false - | Some _ -> true - in - String.iter str ~f:(fun ch -> - let escaped = match ch with - | '%' -> "%%" - | '^' -> - if exclamation then - "^^^^" - else - "^^" - | '&' -> "^&" - | '<' -> "^<" - | '>' -> "^>" - | '\'' -> "^'" - | '"' -> "^\"" - | '`' -> "^`" - | ',' -> "^," - | ';' -> "^;" - | '=' -> "^=" - | '(' -> "^(" - | ')' -> "^)" - | '!' -> "^^!" - | '\n' -> "^\n\n" - | _ -> String.of_char ch - in - Buffer.add_string buffer escaped - ); - Buffer.contents buffer - -let rec print_leftvalue - (buf : Buffer.t) - (lvalue : leftvalue) - ~(bare : bool) - = - match lvalue with - | `Identifier ident -> - if bare || ((String.get ident 0) = '%') then - bprintf buf "%s" ident - else - bprintf buf "!%s!" ident - | `ListAccess (lvalue, index) -> - if bare then - bprintf buf "%a_%a" - (print_leftvalue ~bare: true) lvalue - (print_varint ~bare: true) index - else - bprintf buf "!%a_%a!" - (print_leftvalue ~bare: true) lvalue - (print_varint ~bare: true) index - -and print_varint - (buf : Buffer.t) - (index : varint) - ~(bare : bool) - = - match index with - | `Var lvalue -> - (print_leftvalue ~bare) buf lvalue - | `Int num -> - bprintf buf "%d" num - -let rec print_arith buf (arith : arithmetic) = - match arith with - | `Var lvalue -> - print_leftvalue buf lvalue ~bare: false - | `Int num -> - bprintf buf "%d" num - | `ArithUnary (operator, arith) -> - bprintf buf "%s^(%a^)" operator print_arith arith - | `ArithBinary (operator, left, right) -> ( - let operator = if operator = "%" then "%%" else operator in - bprintf buf "^(%a %s %a^)" - print_arith left - operator - print_arith right - ) - -let print_varstring buf (var : varstring) = - match var with - | `Var lvalue -> - print_leftvalue buf lvalue ~bare: false - | `Str str -> - Buffer.add_string buf (escape str) - | `Rawstr str -> - Buffer.add_string buf str - -let print_varstrings buf (vars : varstrings) = - List.iter vars ~f: (print_varstring buf) - -let print_parameters buf (params : parameters) = - let comsume = ref false in - List.iter params ~f: (fun vars -> - match vars with - | [] -> comsume := true - | _ -> - if !comsume then - comsume := false - else - Buffer.add_char buf ' '; - print_varstrings buf vars - ) - -let print_comparison buf (condition : comparison) = - match condition with - | `TestCompare (operator, expr) -> - bprintf buf "%s %a" - operator - print_varstrings expr - | `UniCompare (operator, expr) -> ( - let sign = match operator with - | "" -> "EQU" - | "!" -> "NEQ" - | _ -> failwith ("Unknown operator: " ^ operator) - in - bprintf buf "%a %s 1" - print_varstrings expr - sign - ) - | `StrCompare (operator, left, right) -> ( - let sign = match operator with - | "==" | "===" -> "EQU" - | "!=" | "!==" -> "NEQ" - | ">" -> "GTR" - | "<" -> "LSS" - | ">=" -> "GEQ" - | "<=" -> "LEQ" - | _ -> failwith ("Unknown operator: " ^ operator) - in - bprintf buf "%a %s %a" - print_varstrings left - sign - print_varstrings right - ) - -let rec print_statement buf (stmt: statement) ~(indent: int) = - Formatutil.print_indent buf indent; - match stmt with - | `Comment comment -> - let len = String.length comment in - bprintf buf "rem%s%s" ( - if len = 0 || (len > 0 && (String.get comment 0) = ' ') then - "" - else - " " - ) comment - | `Raw str -> - Buffer.add_string buf str - | `Label lbl -> - bprintf buf ":%s" lbl - | `Goto lbl -> - bprintf buf "goto %s" lbl - | `Assignment (lvalue, vars) -> - bprintf buf "set %a=%a" - (print_leftvalue ~bare: true) lvalue - print_varstrings vars - | `ArithAssign (lvalue, arith) -> - bprintf buf "set /a %a=%a" - (print_leftvalue ~bare: true) lvalue - print_arith arith - | `Call (name, params) -> - bprintf buf "%a%a" - print_varstrings name - print_parameters params - | `Output (lvalue, name, params) -> - bprintf buf "for /f \"delims=\" %%%%i in ('%a%a') do set %a=%%%%i" - print_varstrings name - print_parameters params - (print_leftvalue ~bare: true) lvalue - | `If (condition, stmts) -> - bprintf buf "if %a (\n%a\n%a)" - print_comparison condition - (print_statements ~indent: (indent + 2)) stmts - Formatutil.print_indent indent - | `IfElse (condition, then_stmts, else_stmts) -> - bprintf buf "if %a (\n%a\n%a) else (\n%a\n%a)" - print_comparison condition - (print_statements ~indent: (indent + 2)) then_stmts - Formatutil.print_indent indent - (print_statements ~indent: (indent + 2)) else_stmts - Formatutil.print_indent indent - | `Empty -> () - -and print_statements: Buffer.t -> statements -> indent:int -> unit = - Formatutil.print_statements ~f: print_statement - -let print (buf: Buffer.t) (program: t) :unit = - print_statements buf program ~indent: 0 diff --git a/src/winbat_functions.ml b/src/winbat_functions.ml deleted file mode 100644 index 75440ac..0000000 --- a/src/winbat_functions.ml +++ /dev/null @@ -1,60 +0,0 @@ -open Core_kernel.Std -open Winbat_ast - -let rec expand_command (name : varstrings) (args : parameters) = - match name with - | [`Str "bash"] -> - `Empty - | [`Str "batch"] -> ( - match args with - | [[`Str raw]] -> - `Raw raw - | _ -> - failwith "batch raw command must have 1 argument of string literal." - ) - | [`Str "println"] -> ( - match args with - | [] -> - `Call ([`Str "echo:"], []) - | _ -> - `Call ([`Str "echo"], args) - ) - | [`Str "print"] -> - `Call ([`Str "echo | set /p ="], [] :: args) - | [`Str "call"] -> ( - match args with - | cmd :: real_args -> - expand_command cmd real_args - | [] -> - failwith "call must have at least 1 argument." - ) - | [`Str "readdir"] -> - `Call ([`Str "dir /w"], args) - | _ -> - `Call (name, args) - -let rec expand_statement (stmt : statement) : statement = - match stmt with - | `Call (name, exprs) -> - expand_command name exprs - | `Output (lvalue, name, exprs) -> - let expaned = expand_command name exprs in ( - match expaned with - | `Call (name, exprs) -> `Output (lvalue, name, exprs) - | _ -> failwith (sprintf "command do not have a return value.") - ) - | `If (condition, stmts) -> - `If (condition, expand_statements stmts) - | `IfElse (condition, then_stmts, else_stmts) -> - `IfElse (condition, - expand_statements then_stmts, - expand_statements else_stmts) - | `Assignment _ - | `ArithAssign _ - | `Comment _ | `Raw _ | `Label _ | `Goto _ | `Empty -> stmt - -and expand_statements (stmts: statements) : statements = - List.map stmts ~f: expand_statement - -let expand (ast : t) : t = - expand_statements ast diff --git a/src/winbat_transform.ml b/src/winbat_transform.ml deleted file mode 100644 index b946d34..0000000 --- a/src/winbat_transform.ml +++ /dev/null @@ -1,200 +0,0 @@ -open Core_kernel.Std -open Batsh_ast - -let rec split_expression - ?(no_split_top = false) - ?(split_call = true) - ?(split_arith = true) - ?(split_string = false) - ?(split_list = true) - ?(split_primitive = false) - (expr : expression) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : (statement Dlist.t * expression) = - let split_binary (left, right) ~split_arith ~split_string = - let assignments_left, left = split_expression left - ~split_arith ~split_string ~symtable ~scope - in - let assignments_right, right = split_expression right - ~split_arith ~split_string ~symtable ~scope - in - Dlist.append assignments_left assignments_right, (left, right) - in - let split_when ~cond current_assignments new_expr = - let split_expr_to_assignment assignments expr - : (statement Dlist.t * expression) = - if no_split_top then - assignments, expr - else - let ident = Symbol_table.Scope.add_temporary_variable scope in - let variable = Identifier ident in - let assignments = Dlist.append - assignments - (Dlist.of_list [Assignment (variable, expr)]) - in - assignments, (Leftvalue variable) - in - if cond then - split_expr_to_assignment current_assignments new_expr - else - current_assignments, new_expr - in - match expr with - | Bool _ | Int _ | Float _ | Leftvalue _ -> - split_when ~cond:split_primitive (Dlist.empty ()) expr - | String str -> - split_when ~cond:split_string (Dlist.empty ()) expr - | ArithUnary (operator, expr) -> - let split = match operator with - | "!" -> true - | _ -> false - in - let assignments, expr = split_expression expr ~symtable ~scope - ~split_arith:split - ~split_string:true - in - split_when ~cond:split_arith assignments (ArithUnary (operator, expr)) - | ArithBinary (operator, left, right) -> - let split = match operator with - | "===" | "!==" | ">" | "<" | ">=" | "<=" -> true - | _ -> false - in - let assignments, (left, right) = split_binary (left, right) - ~split_arith:split - ~split_string:true - in - split_when ~cond:split_arith - assignments (ArithBinary (operator, left, right)) - | Concat (left, right) -> - let assignments, (left, right) = split_binary (left, right) - ~split_arith:true - ~split_string:false - in - split_when ~cond:split_string assignments (Concat (left, right)) - | StrCompare (operator, left, right) -> - let assignments, (left, right) = split_binary (left, right) - ~split_arith:true - ~split_string:false - in - split_when ~cond:true assignments (StrCompare (operator, left, right)) - | Call (ident, exprs) -> - (* If this is a function call, then split all its arguments *) - let split_primitive = Symbol_table.is_function symtable ident in - let assignments, exprs = split_expressions exprs - ~split_primitive ~symtable ~scope - in - split_when ~cond:split_call assignments (Call (ident, exprs)) - | List exprs -> - let assignments, exprs = split_expressions exprs - ~split_primitive:false ~symtable ~scope - in - split_when ~cond:split_list assignments (List exprs) - -and split_expressions - (exprs : expressions) - ~(split_primitive : bool) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : (statement Dlist.t * expressions) = - let assignments, exprs = List.fold exprs ~init: (Dlist.empty (), []) - ~f: (fun (assignments_acc, exprs_acc) expr -> - let assignments, expr = split_expression expr - ~split_string:split_primitive - ~split_primitive - ~symtable ~scope - in - (Dlist.append assignments assignments_acc, expr :: exprs_acc) - ) - in - assignments, List.rev exprs - -let rec split_statement - (stmt : statement) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : statement = - let prepend_assignments assignments stmt : statement = - if Dlist.length assignments = 0 then - stmt - else - Block (Dlist.to_list (Dlist.append assignments (Dlist.of_list [stmt]))) - in - match stmt with - | Empty | Global _ | Comment _ | Return None -> - stmt - | Expression expr -> - let assignments, expr = split_expression expr ~symtable ~scope - ~split_call:false - in - prepend_assignments assignments (Expression expr) - | Return (Some expr) -> - let assignments, expr = split_expression expr ~symtable ~scope in - prepend_assignments assignments (Return (Some expr)) - | Assignment (lvalue, expr) -> - let assignments, expr = split_expression expr - ~symtable - ~scope - ~split_arith:false - ~split_call:false - ~split_list:false - in - prepend_assignments assignments (Assignment (lvalue, expr)) - | If (expr, stmt) -> - let assignments, expr = split_expression expr - ~symtable - ~scope - ~no_split_top:true - in - let stmt = split_statement stmt ~symtable ~scope in - prepend_assignments assignments (If (expr, stmt)) - | IfElse (expr, then_stmt, else_stmt) -> - let assignments, expr = split_expression expr - ~symtable - ~scope - ~no_split_top:true - in - let then_stmt = split_statement then_stmt ~symtable ~scope in - let else_stmt = split_statement else_stmt ~symtable ~scope in - prepend_assignments assignments (IfElse (expr, then_stmt, else_stmt)) - | While (expr, stmt) -> - let assignments, expr = split_expression expr - ~symtable - ~scope - ~no_split_top:true - in - let stmt = split_statement stmt ~symtable ~scope in - prepend_assignments assignments (While (expr, stmt)) - | Block stmts -> - Block (split_statements stmts ~symtable ~scope) - -and split_statements - (stmts : statements) - ~(symtable : Symbol_table.t) - ~(scope : Symbol_table.Scope.t) - : statements = - List.map stmts ~f: (split_statement ~symtable ~scope) - -let split_function - (name, params, stmts) - ~(symtable : Symbol_table.t) - = - let scope = Symbol_table.scope symtable name in - let body = split_statements stmts ~symtable ~scope in - name, params, body - -let split_toplevel - (topl : toplevel) - ~(symtable : Symbol_table.t) - : toplevel = - match topl with - | Statement stmt -> - Statement (split_statement stmt ~symtable - ~scope: (Symbol_table.global_scope symtable)) - | Function func -> - Function (split_function func ~symtable) - -(* Split arithmetic expressions, string literals, string comparisons, - list literals, and command calls *) -let split (ast : Batsh_ast.t) ~(symtable : Symbol_table.t) : Batsh_ast.t = - List.map ast ~f: (split_toplevel ~symtable) diff --git a/tests/arith.batsh b/tests/arith.batsh deleted file mode 100644 index 6607aa7..0000000 --- a/tests/arith.batsh +++ /dev/null @@ -1,16 +0,0 @@ -println(false); -println(true); -println(42); -println(1 + (4 + 6) * 3); -println(8 - 3 % 2); -println(-9 - 9); -println((2 + 8) / 3); -println(2 === 2); -println(6 !== 8); -println(3 > 2); -println(4 < 5); -println(6 >= 2); -println(19 <= 30); -println(!true); -println(!false); -println(!(2 - 1)); diff --git a/tests/array.batsh b/tests/array.batsh deleted file mode 100644 index 3ac42a2..0000000 --- a/tests/array.batsh +++ /dev/null @@ -1,11 +0,0 @@ -a = ["", "y", -1, 1]; -a[0] = 2 * 9; -a[2] = "abx"; -a[4] = "5" ++ a[0]; -println(a[0], a[1], a[2], a[3], a[4]); -a = [1, 2, 3]; -println(a[0], a[1], a[2]); -println(("10" ++ a[0]) * 2); -println(len(a)); -println(len(a) * 8); -//println([1, 2, 3]); diff --git a/tests/assignment.batsh b/tests/assignment.batsh deleted file mode 100644 index 97dd828..0000000 --- a/tests/assignment.batsh +++ /dev/null @@ -1,8 +0,0 @@ -a = "Value: " ++ 1+(4+6)*3; -println(a); -b = 3 + 4; -println(b); -c = a; -println(c); -d = b ++ c; -println(d); diff --git a/tests/bash/arith.sh b/tests/bash/arith.sh deleted file mode 100644 index 2fc5dda..0000000 --- a/tests/bash/arith.sh +++ /dev/null @@ -1,16 +0,0 @@ -"echo" "-e" $((0)) -"echo" "-e" $((1)) -"echo" "-e" $((42)) -"echo" "-e" $((1 + ((4 + 6) * 3))) -"echo" "-e" $((8 - (3 % 2))) -"echo" "-e" $((-9 - 9)) -"echo" "-e" $(((2 + 8) / 3)) -"echo" "-e" $((2 == 2)) -"echo" "-e" $((6 != 8)) -"echo" "-e" $((3 > 2)) -"echo" "-e" $((4 < 5)) -"echo" "-e" $((6 >= 2)) -"echo" "-e" $((19 <= 30)) -"echo" "-e" $((!1)) -"echo" "-e" $((!0)) -"echo" "-e" $((!(2 - 1))) diff --git a/tests/bash/array.sh b/tests/bash/array.sh deleted file mode 100644 index 0a27879..0000000 --- a/tests/bash/array.sh +++ /dev/null @@ -1,13 +0,0 @@ -a=("" "y" $((-1)) $((1))) -a[0]=$((2 * 9)) -a[2]="abx" -a[4]="5""${a[0]}" -"echo" "-e" "${a[0]}" "${a[1]}" "${a[2]}" "${a[3]}" "${a[4]}" -a=($((1)) $((2)) $((3))) -"echo" "-e" "${a[0]}" "${a[1]}" "${a[2]}" -_0="10""${a[0]}" -"echo" "-e" $(($_0 * 2)) -"echo" "-e" "${#a[@]}" -_1="${#a[@]}" -"echo" "-e" $(($_1 * 8)) -#println([1, 2, 3]); diff --git a/tests/bash/assignment.sh b/tests/bash/assignment.sh deleted file mode 100644 index be4437c..0000000 --- a/tests/bash/assignment.sh +++ /dev/null @@ -1,8 +0,0 @@ -a="Value: "$((1 + ((4 + 6) * 3))) -"echo" "-e" "$a" -b=$((3 + 4)) -"echo" "-e" "$b" -c="$a" -"echo" "-e" "$c" -d="$b""$c" -"echo" "-e" "$d" diff --git a/tests/bash/block.sh b/tests/bash/block.sh deleted file mode 100644 index 7bb1461..0000000 --- a/tests/bash/block.sh +++ /dev/null @@ -1,10 +0,0 @@ -#Level 0 Start -"echo" "-e" "Hello" -#Level 1 Start -"echo" "-e" "Lo" -#Level 2 Start -"echo" "-e" "and behold" -#Level 2 End -#Level 1 End -"echo" "-e" "End" -#Level 0 End diff --git a/tests/bash/command.sh b/tests/bash/command.sh deleted file mode 100644 index 54d150f..0000000 --- a/tests/bash/command.sh +++ /dev/null @@ -1,5 +0,0 @@ -"echo" "-e" "Println Called" -cmd="ec""ho" -"$cmd" "Echo Called" -retval=$("echo" "Value 100%") -"echo" "-e" "$retval" diff --git a/tests/bash/comment.sh b/tests/bash/comment.sh deleted file mode 100644 index c93065d..0000000 --- a/tests/bash/comment.sh +++ /dev/null @@ -1,6 +0,0 @@ -a=$((3)) -# This is comment 1 -a=$(($a * 5)) -# This is comment 2 -"echo" "-e" "$a" -#This is comment 3 diff --git a/tests/bash/exists.sh b/tests/bash/exists.sh deleted file mode 100644 index 53f77bc..0000000 --- a/tests/bash/exists.sh +++ /dev/null @@ -1,12 +0,0 @@ -[ -e "Makefile" ] -ex=$((!$?)) -"echo" "-e" "$ex" -[ -e "Makefile" ] -if [ -e "Makefile" ]; then - "echo" "-e" "Yes" -fi -if [ -e "none" ]; then - "echo" "-e" "Impossible" -else - "echo" "-e" "No" -fi diff --git a/tests/bash/function.sh b/tests/bash/function.sh deleted file mode 100644 index d711a97..0000000 --- a/tests/bash/function.sh +++ /dev/null @@ -1,52 +0,0 @@ -# Function call -function func1 { - local p1 - local p2 - p1="$1" - p2="$2" - "echo" "-e" "$p1" "$p2" -} -"func1" "Hello" "World" -# Global and local variables -v1="Global V1" -v2="Global V2" -v3="Global V3" -function func2 { - local v1 - local p - p="$1" - v1="Local ""$p" - "echo" "-e" "$v1" - "echo" "-e" "$v2" - - v3="V3 Modified." -} -"func2" "Var" -"echo" "-e" "$v1" -"echo" "-e" "$v3" -# Return value -function func3 { - local num - num="$1" - "echo" "-ne" $(($num + 41)) - return -} -"func3" $((4)) -"echo" "-e" -ret=$("func3" $((1))) -"echo" "-e" "Returned:" "$ret" -# Argument containing space -function g { - local text - text="$1" - "echo" "-ne" "$text" - return -} -function f { - local text - text="$1" - "echo" "-ne" $("g" "$text") - return -} -test=$("f" "Param with space") -"echo" "-e" "$test" diff --git a/tests/bash/if.sh b/tests/bash/if.sh deleted file mode 100644 index 63bb1a0..0000000 --- a/tests/bash/if.sh +++ /dev/null @@ -1,32 +0,0 @@ -if [ $((2 < 10)) == 1 ]; then - "echo" "-e" "Yes" -fi -if [ $((1)) == 1 ]; then - if [ $((0)) == 1 ]; then - v=$((4 + 1)) - else - v=$((2)) - fi -else -- -fi -"echo" "-e" "$v" -if [ $((2 > 1)) == 1 ]; then - "echo" "-e" "True" -fi -if [ $((1 == 12)) == 1 ]; then - "echo" "-e" "No" -fi -if [ "a" == "b" ]; then - "echo" "-e" "No" -else - "echo" "-e" "a is not b" -fi -num=$((43)) -if [ "43" == "$num" ]; then - "echo" "-e" "43 == num" -fi -_0="43" -if [ $(($_0 == $num)) == 1 ]; then - "echo" "-e" "43 === num" -fi diff --git a/tests/bash/recursion.sh b/tests/bash/recursion.sh deleted file mode 100644 index ab90527..0000000 --- a/tests/bash/recursion.sh +++ /dev/null @@ -1,48 +0,0 @@ -function loop { - local num - num="$1" - "echo" "-e" "$num" - if [ $(($num > 0)) == 1 ]; then - "loop" $(($num - 1)) -fi -} -"loop" $((10)) -function fact { - local num - local _0 - num="$1" - if [ $(($num == 0)) == 1 ]; then - "echo" "-ne" $((1)) - return - else - _0=$("fact" $(($num - 1))) - "echo" "-ne" $(($_0 * $num)) - return - fi -} -"echo" "-e" $("fact" $((5))) -function fibonacci { - local _1 - local num - local _0 - num="$1" - if [ $(($num == 0)) == 1 ]; then - "echo" "-ne" $((0)) - return - else - if [ $(($num == 1)) == 1 ]; then - "echo" "-ne" $((1)) - return - else - _0=$("fibonacci" $(($num - 2))) - _1=$("fibonacci" $(($num - 1))) - "echo" "-ne" $(($_0 + $_1)) - return - fi - fi -} -i=$((0)) -while [ $(($i < 7)) == 1 ]; do - "echo" "-e" $("fibonacci" "$i") - i=$(($i + 1)) -done diff --git a/tests/bash/string.sh b/tests/bash/string.sh deleted file mode 100644 index d48e038..0000000 --- a/tests/bash/string.sh +++ /dev/null @@ -1,18 +0,0 @@ -"echo" "-e" "BYVoid" -"echo" "-e" "Slash/" -"echo" "-e" "Backslash\\" -"echo" "-e" "Quote\"'" -"echo" "-e" "Tab Tab" -#println("Newline\nLine2"); -#println("!"); -"echo" "-e" "http://""www.""byvoid"".com" -"echo" "-e" $((6 / 2))"BYVoid"$((3 + 5)) -_0="3" -"echo" "-e" $((3 + $_0)) -_1="3" -"echo" "-e" $((3 + $_1))"2" -_2="3""2" -"echo" "-e" $((3 + $_2)) -[ "BYVoid" == "BYVoid" ] -_3=$((!$?)) -"echo" "-e" "$_3" diff --git a/tests/bash/while.sh b/tests/bash/while.sh deleted file mode 100644 index ebd44ca..0000000 --- a/tests/bash/while.sh +++ /dev/null @@ -1,17 +0,0 @@ -i=$((0)) -while [ $(($i < 5)) == 1 ]; do - "echo" "-ne" "$i"" " - i=$(($i + 1)) -done -"echo" "-e" -# Fibonacci -n=$((0)) -i=$((0)) -j=$((1)) -while [ $(($n < 40)) == 1 ]; do - k=$(($i + $j)) - i="$j" - j="$k" - n=$(($n + 1)) - "echo" "-e" "$k" -done diff --git a/tests/batch/arith.bat b/tests/batch/arith.bat deleted file mode 100644 index 3853a3a..0000000 --- a/tests/batch/arith.bat +++ /dev/null @@ -1,70 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -setlocal EnableExtensions - -echo 0 -echo 1 -echo 42 -set /a _0=^(1 + ^(^(4 + 6^) * 3^)^) -echo !_0! -set /a _1=^(8 - ^(3 %% 2^)^) -echo !_1! -set /a _2=^(-9 - 9^) -echo !_2! -set /a _3=^(^(2 + 8^) / 3^) -echo !_3! -if 2 EQU 2 ( - set /a _4=1 -) else ( - set /a _4=0 -) -echo !_4! -if 6 NEQ 8 ( - set /a _5=1 -) else ( - set /a _5=0 -) -echo !_5! -if 3 GTR 2 ( - set /a _6=1 -) else ( - set /a _6=0 -) -echo !_6! -if 4 LSS 5 ( - set /a _7=1 -) else ( - set /a _7=0 -) -echo !_7! -if 6 GEQ 2 ( - set /a _8=1 -) else ( - set /a _8=0 -) -echo !_8! -if 19 LEQ 30 ( - set /a _9=1 -) else ( - set /a _9=0 -) -echo !_9! -if 1 NEQ 1 ( - set /a _10=1 -) else ( - set /a _10=0 -) -echo !_10! -if 0 NEQ 1 ( - set /a _11=1 -) else ( - set /a _11=0 -) -echo !_11! -set /a _12=^(2 - 1^) -if !_12! NEQ 1 ( - set /a _13=1 -) else ( - set /a _13=0 -) -echo !_13! diff --git a/tests/batch/array.bat b/tests/batch/array.bat deleted file mode 100644 index c51f4c8..0000000 --- a/tests/batch/array.bat +++ /dev/null @@ -1,25 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -setlocal EnableExtensions - -set a_0= -set a_1=y -set /a a_2=-1 -set /a a_3=1 -set /a a_0=^(2 * 9^) -set a_2=abx -set a_4=5!a_0! -echo !a_0! !a_1! !a_2! !a_3! !a_4! -set /a a_0=1 -set /a a_1=2 -set /a a_2=3 -echo !a_0! !a_1! !a_2! -set _0=10!a_0! -set /a _1=^(!_0! * 2^) -echo !_1! -for /f "delims=" %%i in ('len !a!') do set _2=%%i -echo !_2! -for /f "delims=" %%i in ('len !a!') do set _3=%%i -set /a _4=^(!_3! * 8^) -echo !_4! -rem println([1, 2, 3]); diff --git a/tests/batch/assignment.bat b/tests/batch/assignment.bat deleted file mode 100644 index 0df98c6..0000000 --- a/tests/batch/assignment.bat +++ /dev/null @@ -1,13 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -setlocal EnableExtensions - -set /a _0=^(1 + ^(^(4 + 6^) * 3^)^) -set a=Value: !_0! -echo !a! -set /a b=^(3 + 4^) -echo !b! -set c=!a! -echo !c! -set d=!b!!c! -echo !d! diff --git a/tests/batch/block.bat b/tests/batch/block.bat deleted file mode 100644 index 1b4ac41..0000000 --- a/tests/batch/block.bat +++ /dev/null @@ -1,14 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -setlocal EnableExtensions - -rem Level 0 Start -echo Hello -rem Level 1 Start -echo Lo -rem Level 2 Start -echo and behold -rem Level 2 End -rem Level 1 End -echo End -rem Level 0 End diff --git a/tests/batch/command.bat b/tests/batch/command.bat deleted file mode 100644 index 7a4ec6f..0000000 --- a/tests/batch/command.bat +++ /dev/null @@ -1,9 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -setlocal EnableExtensions - -echo Println Called -set cmd=echo -!cmd! Echo Called -for /f "delims=" %%i in ('echo Value 100%%') do set retval=%%i -echo !retval! diff --git a/tests/batch/comment.bat b/tests/batch/comment.bat deleted file mode 100644 index 6b988e6..0000000 --- a/tests/batch/comment.bat +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -setlocal EnableExtensions - -set /a a=3 -rem This is comment 1 -set /a a=^(!a! * 5^) -rem This is comment 2 -echo !a! -rem This is comment 3 diff --git a/tests/batch/exists.bat b/tests/batch/exists.bat deleted file mode 100644 index 72546fc..0000000 --- a/tests/batch/exists.bat +++ /dev/null @@ -1,23 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -setlocal EnableExtensions - -if exist Makefile ( - set /a ex=1 -) else ( - set /a ex=0 -) -echo !ex! -if exist Makefile ( - -) else ( - -) -if exist Makefile ( - echo Yes -) -if exist none ( - echo Impossible -) else ( - echo No -) diff --git a/tests/batch/function.bat b/tests/batch/function.bat deleted file mode 100644 index 4ba016d..0000000 --- a/tests/batch/function.bat +++ /dev/null @@ -1,69 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -setlocal EnableExtensions - -rem Function call -set _1=World -set _0=Hello -call :func1 _6 0 _0 _1 -echo | set /p ^=!_6! -rem Global and local variables -set v1=Global V1 -set v2=Global V2 -set v3=Global V3 -set _2=Var -call :func2 _7 0 _2 -echo | set /p ^=!_7! -echo !v1! -echo !v3! -rem Return value -set /a _3=4 -call :func3 _8 0 _3 -echo | set /p ^=!_8! -echo: -set /a _4=1 -call :func3 _9 0 _4 -set ret=!_9! -echo Returned: !ret! -rem Argument containing space -set _5=Param with space -call :f _10 0 _5 -set test=!_10! -echo !test! - -goto :EOF -:func1 -set p1_%~2=!%~3! -set p2_%~2=!%~4! -echo !p1_%~2! !p2_%~2! - -goto :EOF -:func2 -set p_%~2=!%~3! -set v1_%~2=Local !p_%~2! -echo !v1_%~2! -echo !v2! -set v3=V3 Modified. - -goto :EOF -:func3 -set num_%~2=!%~3! -set /a _0_%~2=^(!num_%~2! + 41^) -set %~1=!_0_%~2! -goto :EOF - -goto :EOF -:g -set text_%~2=!%~3! -set %~1=!text_%~2! -goto :EOF - -goto :EOF -:f -set text_%~2=!%~3! -set _0_%~2=!text_%~2! -set /a _2_%~2=^(1 + %~2^) -call :g _3_%~2 !_2_%~2! _0_%~2 -set _1_%~2=!_3_%~2! -set %~1=!_1_%~2! -goto :EOF diff --git a/tests/batch/if.bat b/tests/batch/if.bat deleted file mode 100644 index b579162..0000000 --- a/tests/batch/if.bat +++ /dev/null @@ -1,36 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -setlocal EnableExtensions - -if 2 LSS 10 ( - echo Yes -) -if 1 EQU 1 ( - if 1 NEQ 1 ( - set /a v=^(4 + 1^) - ) else ( - set /a v=2 - ) -) else ( - -) -echo !v! -if 2 GTR 1 ( - echo True -) -if 1 EQU 12 ( - echo No -) -if a EQU b ( - echo No -) else ( - echo a is not b -) -set /a num=43 -if 43 EQU !num! ( - echo 43 ^=^= num -) -set _0=43 -if !_0! EQU !num! ( - echo 43 ^=^=^= num -) diff --git a/tests/batch/recursion.bat b/tests/batch/recursion.bat deleted file mode 100644 index 46b04df..0000000 --- a/tests/batch/recursion.bat +++ /dev/null @@ -1,73 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -setlocal EnableExtensions - -set /a _0=10 -call :loop _5 0 _0 -echo | set /p ^=!_5! -set /a _1=5 -call :fact _6 0 _1 -set _2=!_6! -echo !_2! -set /a i=0 -:WHILE_8 -if !i! LSS 7 ( - set _3=!i! - call :fibonacci _7 0 _3 - set _4=!_7! - echo !_4! - set /a i=^(!i! + 1^) - goto WHILE_8 -) - -goto :EOF -:loop -set num_%~2=!%~3! -echo !num_%~2! -if !num_%~2! GTR 0 ( - set /a _0_%~2=^(!num_%~2! - 1^) - set /a _1_%~2=^(1 + %~2^) - call :loop _2_%~2 !_1_%~2! _0_%~2 - echo | set /p ^=!_2_%~2! -) - -goto :EOF -:fact -set num_%~2=!%~3! -if !num_%~2! EQU 0 ( - set %~1=1 - goto :EOF -) else ( - set /a _0_%~2=^(!num_%~2! - 1^) - set /a _3_%~2=^(1 + %~2^) - call :fact _4_%~2 !_3_%~2! _0_%~2 - set _1_%~2=!_4_%~2! - set /a _2_%~2=^(!_1_%~2! * !num_%~2!^) - set %~1=!_2_%~2! - goto :EOF -) - -goto :EOF -:fibonacci -set num_%~2=!%~3! -if !num_%~2! EQU 0 ( - set %~1=0 - goto :EOF -) else ( - if !num_%~2! EQU 1 ( - set %~1=1 - goto :EOF - ) else ( - set /a _0_%~2=^(!num_%~2! - 2^) - set /a _5_%~2=^(1 + %~2^) - call :fibonacci _6_%~2 !_5_%~2! _0_%~2 - set _1_%~2=!_6_%~2! - set /a _2_%~2=^(!num_%~2! - 1^) - set /a _7_%~2=^(1 + %~2^) - call :fibonacci _8_%~2 !_7_%~2! _2_%~2 - set _3_%~2=!_8_%~2! - set /a _4_%~2=^(!_1_%~2! + !_3_%~2!^) - set %~1=!_4_%~2! - goto :EOF - ) -) diff --git a/tests/batch/string.bat b/tests/batch/string.bat deleted file mode 100644 index bee2666..0000000 --- a/tests/batch/string.bat +++ /dev/null @@ -1,30 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -setlocal EnableExtensions - -echo BYVoid -echo Slash/ -echo Backslash\ -echo Quote^"^' -echo Tab Tab -rem println("Newline\nLine2"); -rem println("!"); -echo http://www.byvoid.com -set /a _0=^(6 / 2^) -set /a _1=^(3 + 5^) -echo !_0!BYVoid!_1! -set _2=3 -set /a _3=^(3 + !_2!^) -echo !_3! -set _4=3 -set /a _5=^(3 + !_4!^) -echo !_5!2 -set _6=32 -set /a _7=^(3 + !_6!^) -echo !_7! -if BYVoid EQU BYVoid ( - set /a _8=1 -) else ( - set /a _8=0 -) -echo !_8! diff --git a/tests/batch/while.bat b/tests/batch/while.bat deleted file mode 100644 index 18bb7dc..0000000 --- a/tests/batch/while.bat +++ /dev/null @@ -1,25 +0,0 @@ -@echo off -setlocal EnableDelayedExpansion -setlocal EnableExtensions - -set /a i=0 -:WHILE_0 -if !i! LSS 5 ( - echo | set /p ^=!i! - set /a i=^(!i! + 1^) - goto WHILE_0 -) -echo: -rem Fibonacci -set /a n=0 -set /a i=0 -set /a j=1 -:WHILE_1 -if !n! LSS 40 ( - set /a k=^(!i! + !j!^) - set i=!j! - set j=!k! - set /a n=^(!n! + 1^) - echo !k! - goto WHILE_1 -) diff --git a/tests/block.batsh b/tests/block.batsh deleted file mode 100644 index fb9eab6..0000000 --- a/tests/block.batsh +++ /dev/null @@ -1,14 +0,0 @@ -//Level 0 Start -println("Hello"); -{ - //Level 1 Start - println("Lo"); - { - //Level 2 Start - println("and behold"); - //Level 2 End - } - //Level 1 End -} -println("End"); -//Level 0 End diff --git a/tests/command.batsh b/tests/command.batsh deleted file mode 100644 index 5198b74..0000000 --- a/tests/command.batsh +++ /dev/null @@ -1,5 +0,0 @@ -call("println", "Println Called"); -cmd = "ec" ++ "ho"; -call(cmd, "Echo Called"); -retval = echo("Value 100%"); -println(retval); diff --git a/tests/comment.batsh b/tests/comment.batsh deleted file mode 100644 index 33f5f83..0000000 --- a/tests/comment.batsh +++ /dev/null @@ -1,6 +0,0 @@ -a = 3; -// This is comment 1 -a = a * 5; -// This is comment 2 -println(a); -//This is comment 3 diff --git a/tests/exists.batsh b/tests/exists.batsh deleted file mode 100644 index 84042a9..0000000 --- a/tests/exists.batsh +++ /dev/null @@ -1,11 +0,0 @@ -ex = exists("Makefile"); -println(ex); -exists("Makefile"); -if (exists("Makefile")) { - println("Yes"); -} -if (exists("none")) { - println("Impossible"); -} else { - println("No"); -} diff --git a/tests/function.batsh b/tests/function.batsh deleted file mode 100644 index cc2222c..0000000 --- a/tests/function.batsh +++ /dev/null @@ -1,39 +0,0 @@ -// Function call -function func1(p1, p2) { - println(p1, p2); -} -func1("Hello", "World"); - -// Global and local variables -v1 = "Global V1"; -v2 = "Global V2"; -v3 = "Global V3"; -function func2(p) { - v1 = "Local " ++ p; - println(v1); - println(v2); - global v3; - v3 = "V3 Modified."; -} -func2("Var"); -println(v1); -println(v3); - -// Return value -function func3(num) { - return num + 41; -} -func3(4); -println(); -ret = func3(1); -println("Returned:", ret); - -// Argument containing space -function g(text) { - return text; -} -function f(text) { - return g(text); -} -test = f("Param with space"); -println(test); diff --git a/tests/if.batsh b/tests/if.batsh deleted file mode 100644 index 239d62f..0000000 --- a/tests/if.batsh +++ /dev/null @@ -1,35 +0,0 @@ -if (2 < 10) { - println("Yes"); -} - -if (true) { - if (false){ - v=(4 + 1); - } else { - v = 2; - } -} else { - -} -println(v); - -if (2 > 1) - println("True"); - -if (1 === 12) { - println("No"); -} - -if ("a" == "b") { - println("No"); -} else { - println("a is not b"); -} - -num = 43; -if ("43" == num) { - println("43 == num"); -} -if ("43" === num) { - println("43 === num"); -} diff --git a/tests/output/arith.txt b/tests/output/arith.txt deleted file mode 100644 index 9fdf37f..0000000 --- a/tests/output/arith.txt +++ /dev/null @@ -1,16 +0,0 @@ -0 -1 -42 -31 -7 --18 -3 -1 -1 -1 -1 -1 -1 -0 -1 -0 diff --git a/tests/output/array.txt b/tests/output/array.txt deleted file mode 100644 index 2ba054d..0000000 --- a/tests/output/array.txt +++ /dev/null @@ -1,5 +0,0 @@ -18 y abx 1 518 -1 2 3 -202 -3 -24 diff --git a/tests/output/assignment.txt b/tests/output/assignment.txt deleted file mode 100644 index 5aa8810..0000000 --- a/tests/output/assignment.txt +++ /dev/null @@ -1,4 +0,0 @@ -Value: 31 -7 -Value: 31 -7Value: 31 diff --git a/tests/output/block.txt b/tests/output/block.txt deleted file mode 100644 index c48d28d..0000000 --- a/tests/output/block.txt +++ /dev/null @@ -1,4 +0,0 @@ -Hello -Lo -and behold -End diff --git a/tests/output/command.txt b/tests/output/command.txt deleted file mode 100644 index 2b30d95..0000000 --- a/tests/output/command.txt +++ /dev/null @@ -1,3 +0,0 @@ -Println Called -Echo Called -Value 100% diff --git a/tests/output/comment.txt b/tests/output/comment.txt deleted file mode 100644 index 60d3b2f..0000000 --- a/tests/output/comment.txt +++ /dev/null @@ -1 +0,0 @@ -15 diff --git a/tests/output/exists.txt b/tests/output/exists.txt deleted file mode 100644 index a6d3b18..0000000 --- a/tests/output/exists.txt +++ /dev/null @@ -1,3 +0,0 @@ -1 -Yes -No diff --git a/tests/output/function.txt b/tests/output/function.txt deleted file mode 100644 index 7458a0f..0000000 --- a/tests/output/function.txt +++ /dev/null @@ -1,8 +0,0 @@ -Hello World -Local Var -Global V2 -Global V1 -V3 Modified. -45 -Returned: 42 -Param with space diff --git a/tests/output/if.txt b/tests/output/if.txt deleted file mode 100644 index 90137e8..0000000 --- a/tests/output/if.txt +++ /dev/null @@ -1,6 +0,0 @@ -Yes -2 -True -a is not b -43 == num -43 === num diff --git a/tests/output/recursion.txt b/tests/output/recursion.txt deleted file mode 100644 index 9dd4a22..0000000 --- a/tests/output/recursion.txt +++ /dev/null @@ -1,19 +0,0 @@ -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 -0 -120 -0 -1 -1 -2 -3 -5 -8 diff --git a/tests/output/string.txt b/tests/output/string.txt deleted file mode 100644 index 4b0d09e..0000000 --- a/tests/output/string.txt +++ /dev/null @@ -1,11 +0,0 @@ -BYVoid -Slash/ -Backslash\ -Quote"' -Tab Tab -http://www.byvoid.com -3BYVoid8 -6 -62 -35 -1 diff --git a/tests/output/while.txt b/tests/output/while.txt deleted file mode 100644 index bb1c4dc..0000000 --- a/tests/output/while.txt +++ /dev/null @@ -1,41 +0,0 @@ -0 1 2 3 4 -1 -2 -3 -5 -8 -13 -21 -34 -55 -89 -144 -233 -377 -610 -987 -1597 -2584 -4181 -6765 -10946 -17711 -28657 -46368 -75025 -121393 -196418 -317811 -514229 -832040 -1346269 -2178309 -3524578 -5702887 -9227465 -14930352 -24157817 -39088169 -63245986 -102334155 -165580141 diff --git a/tests/recursion.batsh b/tests/recursion.batsh deleted file mode 100644 index 1d9fd10..0000000 --- a/tests/recursion.batsh +++ /dev/null @@ -1,32 +0,0 @@ -function loop(num) { - println(num); - if (num > 0) { - loop(num - 1); - } -} -loop(10); - -function fact(num) { - if (num === 0) { - return 1; - } else { - return fact(num - 1) * num; - } -} -println(fact(5)); - -function fibonacci(num) { - if (num === 0) { - return 0; - } else if (num === 1) { - return 1; - } else { - return fibonacci(num - 2) + fibonacci(num - 1); - } -} - -i = 0; -while (i < 7) { - println(fibonacci(i)); - i = i + 1; -} diff --git a/tests/string.batsh b/tests/string.batsh deleted file mode 100644 index 9f6ddb3..0000000 --- a/tests/string.batsh +++ /dev/null @@ -1,13 +0,0 @@ -println("BYVoid"); -println("Slash/"); -println("Backslash\\"); -println("Quote\"'"); -println("Tab\tTab"); -//println("Newline\nLine2"); -//println("!"); -println("http://" ++ "www." ++ ("byvoid" ++ ".com")); -println(6 / 2 ++ "BYVoid" ++ 3 + 5); -println(3 + "3"); -println(3 + "3" ++ "2"); -println(3 + ("3" ++ "2")); -println("BYVoid" == "BYVoid"); diff --git a/tests/while.batsh b/tests/while.batsh deleted file mode 100644 index b8c0f0e..0000000 --- a/tests/while.batsh +++ /dev/null @@ -1,18 +0,0 @@ -i = 0; -while (i < 5) { - print(i ++ " "); - i = i + 1; -} -println(); - -// Fibonacci -n = 0; -i = 0; -j = 1; -while (n < 40) { - k = i + j; - i = j; - j = k; - n = n + 1; - println(k); -} From 0293abe1f1751e62805c93de01301eb1975e17c6 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Wed, 22 Oct 2014 17:52:36 +0200 Subject: [PATCH 02/53] Add package definition and BatshAst --- .gitignore | 12 ++++++++++++ batsh.cabal | 19 +++++++++++++++++++ src/BatshAst.hs | 36 ++++++++++++++++++++++++++++++++++++ src/Main.hs | 1 + 4 files changed, 68 insertions(+) create mode 100644 .gitignore create mode 100644 batsh.cabal create mode 100644 src/BatshAst.hs create mode 100644 src/Main.hs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..df44ad5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +dist +cabal-dev +*.o +*.hi +*.chi +*.chs.h +.virtualenv +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +cabal.config diff --git a/batsh.cabal b/batsh.cabal new file mode 100644 index 0000000..ecad7d8 --- /dev/null +++ b/batsh.cabal @@ -0,0 +1,19 @@ +Name: Batsh +Version: 0.1.0 +Cabal-Version: >= 1.2 +License: MIT +Author: Carbo Kuo +Homepage: https://github.com/BYVoid/Batsh +Bug-Reports: https://github.com/BYVoid/Batsh/issues +Category: Compiler +Synopsis: A language that compiles to Bash and Windows Batch +Build-Type: Simple + +Library + Build-Depends: base + Exposed-Modules: BatshAst + Hs-Source-Dirs: src + +Executable main + Main-Is: Main.hs + Hs-Source-Dirs: src diff --git a/src/BatshAst.hs b/src/BatshAst.hs new file mode 100644 index 0000000..698d738 --- /dev/null +++ b/src/BatshAst.hs @@ -0,0 +1,36 @@ +module BatshAst where + +data Literal = Bool Bool + | Int Int + | Float Float + | String String + | List [Expression] + +type Identifier = String + +data UnaryOperator = Not | Negative + +data BinaryOperator = Equal | Plus | Minus | Multiply | Divide + +data LeftValue = Identifier Identifier + | ListAccess (LeftValue, Expression) + +data Expression = LeftValue LeftValue + | Literal Literal + | Unary (UnaryOperator, Expression) + | Binary (BinaryOperator, Expression, Expression) + | Assign (LeftValue, Expression) + | Call (Identifier, [Parameter]) + +type Parameter = Expression + +data Statement = Comment String + | Block [Statement] + | Expression Expression + | If (Expression, Statement) + | IfElse (Expression, Statement, Statement) + | While (Expression, Statement) + | Global Identifier + | Return (Maybe Expression) + +type TopLevel = [Statement] diff --git a/src/Main.hs b/src/Main.hs new file mode 100644 index 0000000..fb1469e --- /dev/null +++ b/src/Main.hs @@ -0,0 +1 @@ +main = putStrLn "Batsh" \ No newline at end of file From 79a9a9f775c48ab809fcfedf347f795f1568c8e3 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Thu, 23 Oct 2014 20:52:29 +0200 Subject: [PATCH 03/53] Skeleton of lexer --- .gitignore | 1 + Makefile | 14 ++++++++++++++ batsh.cabal | 34 ++++++++++++++++++---------------- src/BatshLex.x | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/Main.hs | 6 +++++- 5 files changed, 82 insertions(+), 17 deletions(-) create mode 100644 Makefile create mode 100644 src/BatshLex.x diff --git a/.gitignore b/.gitignore index df44ad5..82dd65a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ cabal-dev .cabal-sandbox/ cabal.sandbox.config cabal.config +batsh diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0e50152 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +batsh: dist/build/batsh/batsh + ln -sf dist/build/batsh/batsh batsh + +dist: + cabal configure + +dist/build/batsh/batsh: dist src/*.hs src/BatshLex.x + cabal build + +.PHONY: clean + +clean: + cabal clean + rm -f batsh diff --git a/batsh.cabal b/batsh.cabal index ecad7d8..7a8d48d 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -1,19 +1,21 @@ -Name: Batsh -Version: 0.1.0 -Cabal-Version: >= 1.2 -License: MIT -Author: Carbo Kuo -Homepage: https://github.com/BYVoid/Batsh -Bug-Reports: https://github.com/BYVoid/Batsh/issues -Category: Compiler -Synopsis: A language that compiles to Bash and Windows Batch -Build-Type: Simple +Name: Batsh +Version: 0.1.0 +Cabal-Version: >= 1.2 +License: MIT +Author: Carbo Kuo +Homepage: https://github.com/BYVoid/Batsh +Bug-Reports: https://github.com/BYVoid/Batsh/issues +Category: Compiler +Synopsis: A language that compiles to Bash and Windows Batch +Build-Type: Simple Library - Build-Depends: base - Exposed-Modules: BatshAst - Hs-Source-Dirs: src + Build-Depends: array, base + Exposed-Modules: BatshAst + Other-Modules: BatshLex + Hs-Source-Dirs: src -Executable main - Main-Is: Main.hs - Hs-Source-Dirs: src +Executable batsh + Main-Is: Main.hs + Other-Modules: BatshAst, BatshLex + Hs-Source-Dirs: src diff --git a/src/BatshLex.x b/src/BatshLex.x new file mode 100644 index 0000000..8e16163 --- /dev/null +++ b/src/BatshLex.x @@ -0,0 +1,44 @@ +{ +module BatshLex where +} + +%wrapper "basic" + +$digit = [0-9] +$oct_digit = [0-7] +$hex_digit = [0-9A-Fa-f] +$alpha = [a-zA-Z] +$underscore = \_ + +@integer = $digit+ +@frac = \. $digit* +@exp = [eE][\-\+]? $digit+ +@float = $digit* @frac @exp? | $digit* @exp +@newline = '\r' | '\n' | "\r\n" +@identifier = [$alpha $underscore] [$alpha $digit $underscore]* + +tokens :- + $white+ ; + "//".* ; + @integer { \s -> Int (read s) } + @float { \s -> Float (read s) } + "true" { \s -> BatshLex.True } + "false" { \s -> BatshLex.False } + @identifier { \s -> Identifier s } + [\=\+\-\*\/\(\)] { \s -> Sym (head s) } + +{ +data Token = Identifier String + | Sym Char + | Int Int + | Float Float + | True + | False + | If + | Else + | While + | Function + | Global + | Return + deriving (Eq,Show) +} diff --git a/src/Main.hs b/src/Main.hs index fb1469e..1a754b4 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1 +1,5 @@ -main = putStrLn "Batsh" \ No newline at end of file +import BatshLex + +main = do + s <- getContents + print (BatshLex.alexScanTokens s) From 125b226ddd1f9063325303168d66ae6626fe1c01 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Fri, 24 Oct 2014 21:26:16 +0200 Subject: [PATCH 04/53] Complete lexer --- batsh.cabal | 9 +--- src/BatshLex.x | 113 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 98 insertions(+), 24 deletions(-) diff --git a/batsh.cabal b/batsh.cabal index 7a8d48d..f1ced30 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -9,13 +9,8 @@ Category: Compiler Synopsis: A language that compiles to Bash and Windows Batch Build-Type: Simple -Library - Build-Depends: array, base - Exposed-Modules: BatshAst - Other-Modules: BatshLex - Hs-Source-Dirs: src - Executable batsh Main-Is: Main.hs - Other-Modules: BatshAst, BatshLex + Other-Modules: BatshAst, BatshLex Hs-Source-Dirs: src + Build-Depends: array, base diff --git a/src/BatshLex.x b/src/BatshLex.x index 8e16163..8862ec2 100644 --- a/src/BatshLex.x +++ b/src/BatshLex.x @@ -1,37 +1,92 @@ +-- This file is the lexical syntax of Batsh. +-- Rules are inspired by Haskell alex examples/haskell.x + { module BatshLex where } %wrapper "basic" -$digit = [0-9] -$oct_digit = [0-7] -$hex_digit = [0-9A-Fa-f] -$alpha = [a-zA-Z] $underscore = \_ +$whitechar = [ \t\n\r\f\v] +$newline = [\r\n] +$digit = [0-9] +$oct_digit = [0-7] +$hex_digit = [0-9A-Fa-f] +$large = [A-Z \xc0-\xd6 \xd8-\xde] +$small = [a-z \xdf-\xf6 \xf8-\xff \_] +$alpha = [$small $large] -@integer = $digit+ -@frac = \. $digit* -@exp = [eE][\-\+]? $digit+ -@float = $digit* @frac @exp? | $digit* @exp -@newline = '\r' | '\n' | "\r\n" @identifier = [$alpha $underscore] [$alpha $digit $underscore]* +-- Integers +@decimal = $digit+ +@hexadecimal = 0x $hex_digit+ +@octal = 0 $oct_digit+ + +-- Float +@frac = \. $digit* +@exp = [eE][\-\+]? $digit+ +@float = $digit* @frac @exp? | $digit* @exp + +-- String +$cntrl = [$large \@\[\\\]\^\_] +@ascii = \^ $cntrl | NUL | SOH | STX | ETX | EOT | ENQ | ACK + | BEL | BS | HT | LF | VT | FF | CR | SO | SI | DLE + | DC1 | DC2 | DC3 | DC4 | NAK | SYN | ETB | CAN | EM + | SUB | ESC | FS | GS | RS | US | SP | DEL +$charesc = [abfnrtv\\\"\'\&] +@escape = \\ ($charesc | @ascii | @decimal | @octal | @hexadecimal) +@gap = \\ $whitechar+ \\ +@string_in = . # [\"\\] | " " | @escape | @gap +@string = \" @string_in* \" + tokens :- - $white+ ; - "//".* ; - @integer { \s -> Int (read s) } - @float { \s -> Float (read s) } - "true" { \s -> BatshLex.True } - "false" { \s -> BatshLex.False } + $white+ ; + @decimal { \s -> Int (read s) } + @float { \s -> Float (read s) } + @string { \s -> String (tail $ init s) } + "true" { \s -> BatshLex.True } + "false" { \s -> BatshLex.False } + "if" { \s -> If } + "else" { \s -> Else } + "while" { \s -> While } + "function" { \s -> Function } + "global" { \s -> Global } + "return" { \s -> Return } + "!" { \s -> Not } + ";" { \s -> Semicolon } + "," { \s -> Comma } + "+" { \s -> Plus } + "-" { \s -> Minus } + "*" { \s -> Multiply } + "/" { \s -> Divide } + "%" { \s -> Modulo } + "++" { \s -> Concat } + "=" { \s -> Assign } + "==" { \s -> Equal } + "!=" { \s -> NotEqual } + "===" { \s -> ArithEqual } + "!==" { \s -> ArithNotEqual } + ">" { \s -> Greater } + "<" { \s -> Less } + ">=" { \s -> GreaterEqual } + "<=" { \s -> LessEqual } + "(" { \s -> LParen } + ")" { \s -> RParen } + "[" { \s -> LBrack } + "]" { \s -> RBrack } + "{" { \s -> LBrace } + "}" { \s -> RBrace } + "//".* { \s -> Comment $ drop 2 s } @identifier { \s -> Identifier s } - [\=\+\-\*\/\(\)] { \s -> Sym (head s) } { data Token = Identifier String - | Sym Char + | Comment String | Int Int | Float Float + | String String | True | False | If @@ -40,5 +95,29 @@ data Token = Identifier String | Function | Global | Return + | Not + | Semicolon + | Comma + | Plus + | Minus + | Multiply + | Divide + | Modulo + | Concat + | Assign + | Equal + | NotEqual + | ArithEqual + | ArithNotEqual + | Greater + | Less + | GreaterEqual + | LessEqual + | LParen + | RParen + | LBrack + | RBrack + | LBrace + | RBrace deriving (Eq,Show) } From 7c6cb950faeff0a1a717c1e48c1632a209021b07 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Fri, 24 Oct 2014 21:58:06 +0200 Subject: [PATCH 05/53] Add unit test for lexer --- Makefile | 8 +++++-- batsh.cabal | 21 +++++++++++++++--- src/BatshLex.x | 9 ++++---- src/Main.hs | 2 +- test/UnitTest.hs | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 test/UnitTest.hs diff --git a/Makefile b/Makefile index 0e50152..5cc3705 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,17 @@ batsh: dist/build/batsh/batsh ln -sf dist/build/batsh/batsh batsh +test: + cabal build + cabal test + dist: - cabal configure + cabal configure --enable-tests dist/build/batsh/batsh: dist src/*.hs src/BatshLex.x cabal build -.PHONY: clean +.PHONY: clean test clean: cabal clean diff --git a/batsh.cabal b/batsh.cabal index f1ced30..9cdfe4f 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -1,6 +1,6 @@ Name: Batsh Version: 0.1.0 -Cabal-Version: >= 1.2 +Cabal-Version: >= 1.8 License: MIT Author: Carbo Kuo Homepage: https://github.com/BYVoid/Batsh @@ -9,8 +9,23 @@ Category: Compiler Synopsis: A language that compiles to Bash and Windows Batch Build-Type: Simple +Library + Build-Depends: array, base + Exposed-Modules: BatshAst, + BatshLex + Hs-Source-Dirs: src + Executable batsh Main-Is: Main.hs - Other-Modules: BatshAst, BatshLex Hs-Source-Dirs: src - Build-Depends: array, base + Build-Depends: array, base, Batsh + +Test-Suite unit-test + Type: exitcode-stdio-1.0 + Main-Is: UnitTest.hs + Hs-Source-Dirs: test + Build-Depends: base, + Batsh, + test-framework, + test-framework-hunit, + HUnit diff --git a/src/BatshLex.x b/src/BatshLex.x index 8862ec2..c54a7c3 100644 --- a/src/BatshLex.x +++ b/src/BatshLex.x @@ -13,16 +13,16 @@ $newline = [\r\n] $digit = [0-9] $oct_digit = [0-7] $hex_digit = [0-9A-Fa-f] -$large = [A-Z \xc0-\xd6 \xd8-\xde] -$small = [a-z \xdf-\xf6 \xf8-\xff \_] -$alpha = [$small $large] +$large = [A-Z \xc0-\xd6 \xd8-\xde] +$small = [a-z \xdf-\xf6 \xf8-\xff \_] +$alpha = [$small $large] @identifier = [$alpha $underscore] [$alpha $digit $underscore]* -- Integers @decimal = $digit+ @hexadecimal = 0x $hex_digit+ -@octal = 0 $oct_digit+ +@octal = 0 $oct_digit+ -- Float @frac = \. $digit* @@ -44,6 +44,7 @@ $charesc = [abfnrtv\\\"\'\&] tokens :- $white+ ; @decimal { \s -> Int (read s) } + @hexadecimal{ \s -> Int (read s) } @float { \s -> Float (read s) } @string { \s -> String (tail $ init s) } "true" { \s -> BatshLex.True } diff --git a/src/Main.hs b/src/Main.hs index 1a754b4..5ada1e9 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,4 +1,4 @@ -import BatshLex +import qualified BatshLex main = do s <- getContents diff --git a/test/UnitTest.hs b/test/UnitTest.hs new file mode 100644 index 0000000..937efdd --- /dev/null +++ b/test/UnitTest.hs @@ -0,0 +1,58 @@ +import Control.Monad +import Data.Monoid +import Test.HUnit +import Test.Framework +import Test.Framework.Providers.HUnit +import qualified BatshLex + +lexerTest :: Assertion +lexerTest = do + let testSingle str expected = do + let tokens = BatshLex.alexScanTokens str + let token = head tokens + assertEqual "Number of tokens" 1 (length tokens) + assertEqual (show token) expected token + testSingle "variable" $ BatshLex.Identifier "variable" + testSingle "//a line comment" $ BatshLex.Comment "a line comment" + testSingle "42" $ BatshLex.Int 42 + testSingle "0xFF" $ BatshLex.Int 255 + testSingle "3.14" $ BatshLex.Float 3.14 + testSingle "1E-8" $ BatshLex.Float 1e-8 + testSingle "\"string\\n\"" $ BatshLex.String "string\\n" + testSingle "true" BatshLex.True + testSingle "false" BatshLex.False + testSingle "if" BatshLex.If + testSingle "else" BatshLex.Else + testSingle "while" BatshLex.While + testSingle "function" BatshLex.Function + testSingle "global" BatshLex.Global + testSingle "return" BatshLex.Return + testSingle "!" BatshLex.Not + testSingle ";" BatshLex.Semicolon + testSingle "," BatshLex.Comma + testSingle "+" BatshLex.Plus + testSingle "-" BatshLex.Minus + testSingle "*" BatshLex.Multiply + testSingle "/" BatshLex.Divide + testSingle "%" BatshLex.Modulo + testSingle "++" BatshLex.Concat + testSingle "=" BatshLex.Assign + testSingle "==" BatshLex.Equal + testSingle "!=" BatshLex.NotEqual + testSingle "===" BatshLex.ArithEqual + testSingle "!==" BatshLex.ArithNotEqual + testSingle ">" BatshLex.Greater + testSingle "<" BatshLex.Less + testSingle ">=" BatshLex.GreaterEqual + testSingle "<=" BatshLex.LessEqual + testSingle "(" BatshLex.LParen + testSingle ")" BatshLex.RParen + testSingle "[" BatshLex.LBrack + testSingle "]" BatshLex.RBrack + testSingle "{" BatshLex.LBrace + testSingle "}" BatshLex.RBrace + +main :: IO () +main = defaultMainWithOpts + [testCase "Lexer" lexerTest] + mempty From 2b1bfd2939f6459fe2d9900a09fa95107eeba2d9 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Sat, 25 Oct 2014 08:16:27 +0100 Subject: [PATCH 06/53] Add BatshLex.scanTokens --- src/BatshLex.x | 3 +++ src/Main.hs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/BatshLex.x b/src/BatshLex.x index c54a7c3..7964a23 100644 --- a/src/BatshLex.x +++ b/src/BatshLex.x @@ -121,4 +121,7 @@ data Token = Identifier String | LBrace | RBrace deriving (Eq,Show) + +scanTokens = alexScanTokens + } diff --git a/src/Main.hs b/src/Main.hs index 5ada1e9..e825faf 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -2,4 +2,4 @@ import qualified BatshLex main = do s <- getContents - print (BatshLex.alexScanTokens s) + print (BatshLex.scanTokens s) From 9e6547c8e08140caee4f0b4d896e4527e0cd9b14 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Sat, 25 Oct 2014 23:54:24 +0100 Subject: [PATCH 07/53] Skeleton of BatshParser --- batsh.cabal | 3 ++- src/BatshAst.hs | 6 ++++++ src/BatshParser.y | 35 +++++++++++++++++++++++++++++++++++ test/UnitTest.hs | 15 ++++++++++++--- 4 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 src/BatshParser.y diff --git a/batsh.cabal b/batsh.cabal index 9cdfe4f..cca6098 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -12,7 +12,8 @@ Build-Type: Simple Library Build-Depends: array, base Exposed-Modules: BatshAst, - BatshLex + BatshLex, + BatshParser Hs-Source-Dirs: src Executable batsh diff --git a/src/BatshAst.hs b/src/BatshAst.hs index 698d738..62d4615 100644 --- a/src/BatshAst.hs +++ b/src/BatshAst.hs @@ -5,15 +5,19 @@ data Literal = Bool Bool | Float Float | String String | List [Expression] + deriving (Eq,Show) type Identifier = String data UnaryOperator = Not | Negative + deriving (Eq,Show) data BinaryOperator = Equal | Plus | Minus | Multiply | Divide + deriving (Eq,Show) data LeftValue = Identifier Identifier | ListAccess (LeftValue, Expression) + deriving (Eq,Show) data Expression = LeftValue LeftValue | Literal Literal @@ -21,6 +25,7 @@ data Expression = LeftValue LeftValue | Binary (BinaryOperator, Expression, Expression) | Assign (LeftValue, Expression) | Call (Identifier, [Parameter]) + deriving (Eq,Show) type Parameter = Expression @@ -32,5 +37,6 @@ data Statement = Comment String | While (Expression, Statement) | Global Identifier | Return (Maybe Expression) + deriving (Eq,Show) type TopLevel = [Statement] diff --git a/src/BatshParser.y b/src/BatshParser.y new file mode 100644 index 0000000..1ad85c9 --- /dev/null +++ b/src/BatshParser.y @@ -0,0 +1,35 @@ +{ +module BatshParser where + +import qualified BatshAst +import qualified BatshLex +} + +%name parseTopLevel +%tokentype { BatshLex.Token } +%error { parseError } + +%token + ident { BatshLex.Identifier $$ } + int { BatshLex.Int $$ } + ',' { BatshLex.Comma } + '[' { BatshLex.LBrack } + ']' { BatshLex.RBrack } +%% + +program : expression { BatshAst.Expression $1 } + +expression : leftvalue { BatshAst.LeftValue $1 } + | literal { BatshAst.Literal $1 } + +literal : int { BatshAst.Int $1 } + +leftvalue : ident { BatshAst.Identifier $1 } + +{ +parseError :: [BatshLex.Token] -> a +parseError _ = error "Parse error" + +parse :: String -> BatshAst.Statement +parse = parseTopLevel . BatshLex.scanTokens +} diff --git a/test/UnitTest.hs b/test/UnitTest.hs index 937efdd..0f4f7d3 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -3,10 +3,12 @@ import Data.Monoid import Test.HUnit import Test.Framework import Test.Framework.Providers.HUnit +import qualified BatshAst import qualified BatshLex +import qualified BatshParser -lexerTest :: Assertion -lexerTest = do +testLexer :: Assertion +testLexer = do let testSingle str expected = do let tokens = BatshLex.alexScanTokens str let token = head tokens @@ -52,7 +54,14 @@ lexerTest = do testSingle "{" BatshLex.LBrace testSingle "}" BatshLex.RBrace +testParser :: Assertion +testParser = do + let ast = BatshParser.parse "3" + assertEqual (show ast) + (BatshAst.Expression $ BatshAst.Literal $ BatshAst.Int 3) ast + main :: IO () main = defaultMainWithOpts - [testCase "Lexer" lexerTest] + [testCase "Lexer" testLexer, + testCase "Parser" testParser] mempty From e81afa9039756d2ba9dc6d6bc47450981d6513ec Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Sun, 26 Oct 2014 18:54:32 +0100 Subject: [PATCH 08/53] Parsing rules: toplevel, statement, list --- src/BatshAst.hs | 6 +++- src/BatshParser.y | 74 +++++++++++++++++++++++++++++++++++++---------- test/UnitTest.hs | 5 ++-- 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/src/BatshAst.hs b/src/BatshAst.hs index 62d4615..49e325a 100644 --- a/src/BatshAst.hs +++ b/src/BatshAst.hs @@ -39,4 +39,8 @@ data Statement = Comment String | Return (Maybe Expression) deriving (Eq,Show) -type TopLevel = [Statement] +data TopLevel = Statement Statement + | Function (Identifier, [Statement]) + deriving (Eq,Show) + +type Program = [TopLevel] diff --git a/src/BatshParser.y b/src/BatshParser.y index 1ad85c9..dc26652 100644 --- a/src/BatshParser.y +++ b/src/BatshParser.y @@ -1,35 +1,77 @@ +-- This file includes the parsing rules of Batsh. + { -module BatshParser where +module BatshParser(parse, + parseTopLevel, + parseStatement, + parseExpression) where import qualified BatshAst import qualified BatshLex } -%name parseTopLevel -%tokentype { BatshLex.Token } -%error { parseError } +-- parse function terminal name +%name program program +%name toplevel toplevel +%name statement statement +%name expression expression + +%tokentype { BatshLex.Token } +%error { parseError } %token - ident { BatshLex.Identifier $$ } - int { BatshLex.Int $$ } - ',' { BatshLex.Comma } - '[' { BatshLex.LBrack } - ']' { BatshLex.RBrack } + ident { BatshLex.Identifier $$ } + comment { BatshLex.Comment $$ } + int { BatshLex.Int $$ } + float { BatshLex.Float $$ } + string { BatshLex.String $$ } + true { BatshLex.True } + false { BatshLex.False } + ',' { BatshLex.Comma } + '[' { BatshLex.LBrack } + ']' { BatshLex.RBrack } %% -program : expression { BatshAst.Expression $1 } +program : toplevels { $1 } + +toplevels : { [] } + | toplevel { [$1] } + | toplevel toplevels { $1 : $2 } + +toplevel : statement { BatshAst.Statement $1 } + +statement : comment { BatshAst.Comment $1 } + | expression { BatshAst.Expression $1 } -expression : leftvalue { BatshAst.LeftValue $1 } - | literal { BatshAst.Literal $1 } +expression : leftvalue { BatshAst.LeftValue $1 } + | literal { BatshAst.Literal $1 } -literal : int { BatshAst.Int $1 } +literal : true { BatshAst.Bool True } + | false { BatshAst.Bool False } + | int { BatshAst.Int $1 } + | float { BatshAst.Float $1 } + | string { BatshAst.String $1 } + | '[' list ']' { BatshAst.List $2 } -leftvalue : ident { BatshAst.Identifier $1 } +list : { [] } + | expression { [$1] } + | expression ',' list { $1 : $3 } + +leftvalue : ident { BatshAst.Identifier $1 } { parseError :: [BatshLex.Token] -> a parseError _ = error "Parse error" -parse :: String -> BatshAst.Statement -parse = parseTopLevel . BatshLex.scanTokens +parse :: String -> BatshAst.Program +parse = program . BatshLex.scanTokens + +parseTopLevel :: String -> BatshAst.TopLevel +parseTopLevel = toplevel . BatshLex.scanTokens + +parseStatement :: String -> BatshAst.Statement +parseStatement = statement . BatshLex.scanTokens + +parseExpression :: String -> BatshAst.Expression +parseExpression = expression . BatshLex.scanTokens } diff --git a/test/UnitTest.hs b/test/UnitTest.hs index 0f4f7d3..5ef2d73 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -56,9 +56,8 @@ testLexer = do testParser :: Assertion testParser = do - let ast = BatshParser.parse "3" - assertEqual (show ast) - (BatshAst.Expression $ BatshAst.Literal $ BatshAst.Int 3) ast + let ast = BatshParser.parseExpression "3" + assertEqual (show ast) (BatshAst.Literal $ BatshAst.Int 3) ast main :: IO () main = defaultMainWithOpts From 5b15daf9b9b29453d63464d0194d4627e50a58df Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Sun, 26 Oct 2014 19:46:52 +0100 Subject: [PATCH 09/53] Parsing rules: statements, expressions, function --- src/BatshAst.hs | 3 +- src/BatshParser.y | 100 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 77 insertions(+), 26 deletions(-) diff --git a/src/BatshAst.hs b/src/BatshAst.hs index 49e325a..c39b42f 100644 --- a/src/BatshAst.hs +++ b/src/BatshAst.hs @@ -13,6 +13,7 @@ data UnaryOperator = Not | Negative deriving (Eq,Show) data BinaryOperator = Equal | Plus | Minus | Multiply | Divide + | Modulo | Concat deriving (Eq,Show) data LeftValue = Identifier Identifier @@ -40,7 +41,7 @@ data Statement = Comment String deriving (Eq,Show) data TopLevel = Statement Statement - | Function (Identifier, [Statement]) + | Function (Identifier, [Identifier], [Statement]) deriving (Eq,Show) type Program = [TopLevel] diff --git a/src/BatshParser.y b/src/BatshParser.y index dc26652..9d3df24 100644 --- a/src/BatshParser.y +++ b/src/BatshParser.y @@ -27,37 +27,87 @@ import qualified BatshLex string { BatshLex.String $$ } true { BatshLex.True } false { BatshLex.False } + function { BatshLex.Function } + global { BatshLex.Global } + return { BatshLex.Return } + '!' { BatshLex.Not } + ';' { BatshLex.Semicolon } + '+' { BatshLex.Plus } + '-' { BatshLex.Minus } + '*' { BatshLex.Multiply } + '/' { BatshLex.Divide } + '%' { BatshLex.Modulo } + '++' { BatshLex.Concat } ',' { BatshLex.Comma } + '(' { BatshLex.LParen } + ')' { BatshLex.RParen } '[' { BatshLex.LBrack } ']' { BatshLex.RBrack } -%% - -program : toplevels { $1 } - -toplevels : { [] } - | toplevel { [$1] } - | toplevel toplevels { $1 : $2 } - -toplevel : statement { BatshAst.Statement $1 } + '{' { BatshLex.LBrace } + '}' { BatshLex.RBrace } -statement : comment { BatshAst.Comment $1 } - | expression { BatshAst.Expression $1 } +%left '++' +%nonassoc '!' +%left '+' '-' +%left '*' '/' '%' -expression : leftvalue { BatshAst.LeftValue $1 } - | literal { BatshAst.Literal $1 } - -literal : true { BatshAst.Bool True } - | false { BatshAst.Bool False } - | int { BatshAst.Int $1 } - | float { BatshAst.Float $1 } - | string { BatshAst.String $1 } - | '[' list ']' { BatshAst.List $2 } - -list : { [] } - | expression { [$1] } - | expression ',' list { $1 : $3 } +%% -leftvalue : ident { BatshAst.Identifier $1 } +program : toplevels { $1 } + +toplevel : statement { BatshAst.Statement $1 } + | function ident '(' idents ')' + '{' statements '}' { BatshAst.Function ($2, $4, $7)} + +statement : comment { BatshAst.Comment $1 } + | '{' statements '}' { BatshAst.Block $2 } + | expression ';' { BatshAst.Expression $1 } + | global ident ';' { BatshAst.Global $2 } + | return expression ';' { BatshAst.Return $ Just $2 } + | return ';' { BatshAst.Return $ Nothing } + +expression : leftvalue { BatshAst.LeftValue $1 } + | literal { BatshAst.Literal $1 } + | ident '(' expressions ')' { BatshAst.Call ($1, $3) } + | '(' expression ')' { $2 } + | unary { BatshAst.Unary $1 } + | binary { BatshAst.Binary $1 } + +unary : '!' expression { BatshAst.Not, $2 } + | '-' expression { BatshAst.Negative, $2 } + +binary : expression '+' expression { BatshAst.Plus, $1, $3 } + | expression '-' expression { BatshAst.Minus, $1, $3 } + | expression '*' expression { BatshAst.Multiply, $1, $3 } + | expression '/' expression { BatshAst.Divide, $1, $3 } + | expression '%' expression { BatshAst.Modulo, $1, $3 } + | expression '++' expression { BatshAst.Concat, $1, $3 } + +literal : true { BatshAst.Bool True } + | false { BatshAst.Bool False } + | int { BatshAst.Int $1 } + | float { BatshAst.Float $1 } + | string { BatshAst.String $1 } + | '[' expressions ']' { BatshAst.List $2 } + +leftvalue : ident { BatshAst.Identifier $1 } + | leftvalue '[' expression ']' { BatshAst.ListAccess ($1, $3) } + +toplevels : { [] } + | toplevel { [$1] } + | toplevel toplevels { $1 : $2 } + +statements : { [] } + | statement { [$1] } + | statement statements { $1 : $2 } + +expressions : { [] } + | expression { [$1] } + | expression ',' expressions { $1 : $3 } + +idents : { [] } + | ident { [$1] } + | ident ',' idents { $1 : $3 } { parseError :: [BatshLex.Token] -> a From 1db7f810118e4e98cc8b0df17303a9f7f76ae6bb Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Mon, 27 Oct 2014 20:37:11 +0100 Subject: [PATCH 10/53] Resolve reduce/reduce confilits --- src/BatshParser.y | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/BatshParser.y b/src/BatshParser.y index 9d3df24..74687bc 100644 --- a/src/BatshParser.y +++ b/src/BatshParser.y @@ -94,11 +94,9 @@ leftvalue : ident { BatshAst.Identifier $1 } | leftvalue '[' expression ']' { BatshAst.ListAccess ($1, $3) } toplevels : { [] } - | toplevel { [$1] } | toplevel toplevels { $1 : $2 } statements : { [] } - | statement { [$1] } | statement statements { $1 : $2 } expressions : { [] } From dc64c9a0e0c05dd121dac207a6e758f7845b231f Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Mon, 27 Oct 2014 21:44:10 +0100 Subject: [PATCH 11/53] Parsing rules: binary expressions, if, while --- src/BatshAst.hs | 7 ++++--- src/BatshLex.x | 4 ++++ src/BatshParser.y | 51 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/BatshAst.hs b/src/BatshAst.hs index c39b42f..1243bea 100644 --- a/src/BatshAst.hs +++ b/src/BatshAst.hs @@ -9,11 +9,12 @@ data Literal = Bool Bool type Identifier = String -data UnaryOperator = Not | Negative +data UnaryOperator = Not | Negate deriving (Eq,Show) -data BinaryOperator = Equal | Plus | Minus | Multiply | Divide - | Modulo | Concat +data BinaryOperator = Plus | Minus | Multiply | Divide | Modulo | Concat + | Equal | NotEqual | ArithEqual | ArithNotEqual | Greater | Less + | GreaterEqual | LessEqual | And | Or deriving (Eq,Show) data LeftValue = Identifier Identifier diff --git a/src/BatshLex.x b/src/BatshLex.x index 7964a23..df75a84 100644 --- a/src/BatshLex.x +++ b/src/BatshLex.x @@ -73,6 +73,8 @@ tokens :- "<" { \s -> Less } ">=" { \s -> GreaterEqual } "<=" { \s -> LessEqual } + "&&" { \s -> And } + "||" { \s -> Or } "(" { \s -> LParen } ")" { \s -> RParen } "[" { \s -> LBrack } @@ -114,6 +116,8 @@ data Token = Identifier String | Less | GreaterEqual | LessEqual + | And + | Or | LParen | RParen | LBrack diff --git a/src/BatshParser.y b/src/BatshParser.y index 74687bc..dffcd99 100644 --- a/src/BatshParser.y +++ b/src/BatshParser.y @@ -20,36 +20,56 @@ import qualified BatshLex %error { parseError } %token - ident { BatshLex.Identifier $$ } - comment { BatshLex.Comment $$ } int { BatshLex.Int $$ } float { BatshLex.Float $$ } string { BatshLex.String $$ } true { BatshLex.True } false { BatshLex.False } + if { BatshLex.If } + else { BatshLex.Else } + while { BatshLex.While } function { BatshLex.Function } global { BatshLex.Global } return { BatshLex.Return } '!' { BatshLex.Not } ';' { BatshLex.Semicolon } + ',' { BatshLex.Comma } '+' { BatshLex.Plus } '-' { BatshLex.Minus } '*' { BatshLex.Multiply } '/' { BatshLex.Divide } '%' { BatshLex.Modulo } '++' { BatshLex.Concat } - ',' { BatshLex.Comma } + '=' { BatshLex.Assign } + '==' { BatshLex.Equal } + '!=' { BatshLex.NotEqual } + '===' { BatshLex.ArithEqual } + '!==' { BatshLex.ArithNotEqual } + '>' { BatshLex.Greater } + '<' { BatshLex.Less } + '>=' { BatshLex.GreaterEqual } + '<=' { BatshLex.LessEqual } + '&&' { BatshLex.And } + '||' { BatshLex.Or } '(' { BatshLex.LParen } ')' { BatshLex.RParen } '[' { BatshLex.LBrack } ']' { BatshLex.RBrack } '{' { BatshLex.LBrace } '}' { BatshLex.RBrace } + comment { BatshLex.Comment $$ } + ident { BatshLex.Identifier $$ } +%right if else +%right '=' +%left '||' +%left '&&' +%nonassoc '==' '!=' '===' '!==' +%nonassoc '>' '<' '>=' '<=' %left '++' -%nonassoc '!' %left '+' '-' %left '*' '/' '%' +%nonassoc '!' '-' %% @@ -65,6 +85,16 @@ statement : comment { BatshAst.Comment $1 } | global ident ';' { BatshAst.Global $2 } | return expression ';' { BatshAst.Return $ Just $2 } | return ';' { BatshAst.Return $ Nothing } + | if_statement { $1 } + | loop_statement { $1 } + +if_statement : if '(' expression ')' + statement %prec if { BatshAst.If ($3, $5) } + | if '(' expression ')' + statement else statement { BatshAst.If ($3, $5) } + +loop_statement: while '(' expression ')' + statement { BatshAst.While ($3, $5) } expression : leftvalue { BatshAst.LeftValue $1 } | literal { BatshAst.Literal $1 } @@ -72,9 +102,10 @@ expression : leftvalue { BatshAst.LeftValue $1 } | '(' expression ')' { $2 } | unary { BatshAst.Unary $1 } | binary { BatshAst.Binary $1 } + | leftvalue '=' expression { BatshAst.Assign ($1, $3) } unary : '!' expression { BatshAst.Not, $2 } - | '-' expression { BatshAst.Negative, $2 } + | '-' expression %prec '-' { BatshAst.Negate, $2 } binary : expression '+' expression { BatshAst.Plus, $1, $3 } | expression '-' expression { BatshAst.Minus, $1, $3 } @@ -82,6 +113,16 @@ binary : expression '+' expression { BatshAst.Plus, $1, $3 } | expression '/' expression { BatshAst.Divide, $1, $3 } | expression '%' expression { BatshAst.Modulo, $1, $3 } | expression '++' expression { BatshAst.Concat, $1, $3 } + | expression '==' expression { BatshAst.Equal, $1, $3 } + | expression '!=' expression { BatshAst.NotEqual, $1, $3 } + | expression '===' expression { BatshAst.ArithEqual, $1, $3 } + | expression '!==' expression { BatshAst.ArithNotEqual, $1, $3 } + | expression '>' expression { BatshAst.Greater, $1, $3 } + | expression '<' expression { BatshAst.Less, $1, $3 } + | expression '>=' expression { BatshAst.GreaterEqual, $1, $3 } + | expression '<=' expression { BatshAst.LessEqual, $1, $3 } + | expression '&&' expression { BatshAst.And, $1, $3 } + | expression '||' expression { BatshAst.Or, $1, $3 } literal : true { BatshAst.Bool True } | false { BatshAst.Bool False } From 5d6eb17da60b37c2612b27ea77074ee9fe4c122c Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Mon, 27 Oct 2014 22:00:48 +0100 Subject: [PATCH 12/53] Unit test for BatshParser --- src/BatshParser.y | 2 +- test/UnitTest.hs | 28 +++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/BatshParser.y b/src/BatshParser.y index dffcd99..5f275b8 100644 --- a/src/BatshParser.y +++ b/src/BatshParser.y @@ -91,7 +91,7 @@ statement : comment { BatshAst.Comment $1 } if_statement : if '(' expression ')' statement %prec if { BatshAst.If ($3, $5) } | if '(' expression ')' - statement else statement { BatshAst.If ($3, $5) } + statement else statement { BatshAst.IfElse ($3, $5, $7) } loop_statement: while '(' expression ')' statement { BatshAst.While ($3, $5) } diff --git a/test/UnitTest.hs b/test/UnitTest.hs index 5ef2d73..93bde9a 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -3,7 +3,7 @@ import Data.Monoid import Test.HUnit import Test.Framework import Test.Framework.Providers.HUnit -import qualified BatshAst +import BatshAst import qualified BatshLex import qualified BatshParser @@ -47,6 +47,8 @@ testLexer = do testSingle "<" BatshLex.Less testSingle ">=" BatshLex.GreaterEqual testSingle "<=" BatshLex.LessEqual + testSingle "&&" BatshLex.And + testSingle "||" BatshLex.Or testSingle "(" BatshLex.LParen testSingle ")" BatshLex.RParen testSingle "[" BatshLex.LBrack @@ -56,8 +58,28 @@ testLexer = do testParser :: Assertion testParser = do - let ast = BatshParser.parseExpression "3" - assertEqual (show ast) (BatshAst.Literal $ BatshAst.Int 3) ast + let testAst :: (Show a, Eq a) => (String -> a) -> String -> a -> Assertion; + testAst parser code expected = + assertEqual (show ast) expected ast + where ast = parser code + let testProgram = testAst BatshParser.parse + let testTopLevel = testAst BatshParser.parseTopLevel + let testStatement = testAst BatshParser.parseStatement + let testExpression = testAst BatshParser.parseExpression + -- Expression + testExpression "3" (Literal $ Int 3) + testExpression "[4.2 + 3, \"str\", []]" (Literal $ List [Binary (Plus, + Literal $ Float 4.2 , Literal $ Int 3), Literal $ String "str", + Literal $ List []]) + testExpression "a+2+9*4e2 > 5 || true && 4 != \"str\"" (Binary (Or, Binary ( + Greater, Binary (Plus, Binary (Plus, LeftValue (Identifier "a"), Literal ( + Int 2)), Binary (Multiply, Literal (Int 9), Literal (Float 400.0))), Literal + (Int 5)), Binary (And, Literal (Bool True), Binary (NotEqual, Literal (Int + 4), Literal (String "str"))))) + -- Statement + testStatement "func(4);" (Expression $ Call ("func", [Literal $ Int 4])) + testStatement "if (1) if (2) {true;} else {}" (If (Literal (Int 1), IfElse ( + Literal (Int 2), Block [Expression (Literal (Bool True))], Block []))) main :: IO () main = defaultMainWithOpts From aac4234c113b25d893c3fe792426225469a0da27 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Tue, 28 Oct 2014 19:53:37 +0100 Subject: [PATCH 13/53] Code file parsing test --- batsh.cabal | 5 +- src/Batsh.hs | 14 ++++ src/BatshAst.hs | 14 ++-- src/Main.hs | 5 +- test/UnitTest.hs | 17 ++++- test/testcase/Batsh/arith.batsh | 16 +++++ test/testcase/BatshAst/arith.parsed | 102 ++++++++++++++++++++++++++++ 7 files changed, 161 insertions(+), 12 deletions(-) create mode 100644 src/Batsh.hs create mode 100644 test/testcase/Batsh/arith.batsh create mode 100644 test/testcase/BatshAst/arith.parsed diff --git a/batsh.cabal b/batsh.cabal index cca6098..3d265b0 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -11,7 +11,8 @@ Build-Type: Simple Library Build-Depends: array, base - Exposed-Modules: BatshAst, + Exposed-Modules: Batsh, + BatshAst, BatshLex, BatshParser Hs-Source-Dirs: src @@ -19,7 +20,7 @@ Library Executable batsh Main-Is: Main.hs Hs-Source-Dirs: src - Build-Depends: array, base, Batsh + Build-Depends: array, base, Batsh, pretty-show Test-Suite unit-test Type: exitcode-stdio-1.0 diff --git a/src/Batsh.hs b/src/Batsh.hs new file mode 100644 index 0000000..ff1ce96 --- /dev/null +++ b/src/Batsh.hs @@ -0,0 +1,14 @@ +module Batsh where + +import BatshAst +import qualified BatshParser + +parseFromFile :: FilePath -> IO Program +parseFromFile path = do + code <- readFile path + return (BatshParser.parse code) + +parseFromAstFile :: FilePath -> IO Program +parseFromAstFile path = do + code <- readFile path + return (read code :: Program) diff --git a/src/BatshAst.hs b/src/BatshAst.hs index 1243bea..9e59be8 100644 --- a/src/BatshAst.hs +++ b/src/BatshAst.hs @@ -5,21 +5,21 @@ data Literal = Bool Bool | Float Float | String String | List [Expression] - deriving (Eq,Show) + deriving (Eq,Read,Show) type Identifier = String data UnaryOperator = Not | Negate - deriving (Eq,Show) + deriving (Eq,Read,Show) data BinaryOperator = Plus | Minus | Multiply | Divide | Modulo | Concat | Equal | NotEqual | ArithEqual | ArithNotEqual | Greater | Less | GreaterEqual | LessEqual | And | Or - deriving (Eq,Show) + deriving (Eq,Read,Show) data LeftValue = Identifier Identifier | ListAccess (LeftValue, Expression) - deriving (Eq,Show) + deriving (Eq,Read,Show) data Expression = LeftValue LeftValue | Literal Literal @@ -27,7 +27,7 @@ data Expression = LeftValue LeftValue | Binary (BinaryOperator, Expression, Expression) | Assign (LeftValue, Expression) | Call (Identifier, [Parameter]) - deriving (Eq,Show) + deriving (Eq,Read,Show) type Parameter = Expression @@ -39,10 +39,10 @@ data Statement = Comment String | While (Expression, Statement) | Global Identifier | Return (Maybe Expression) - deriving (Eq,Show) + deriving (Eq,Read,Show) data TopLevel = Statement Statement | Function (Identifier, [Identifier], [Statement]) - deriving (Eq,Show) + deriving (Eq,Read,Show) type Program = [TopLevel] diff --git a/src/Main.hs b/src/Main.hs index e825faf..1106697 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,5 +1,6 @@ -import qualified BatshLex +import qualified BatshParser +import Text.Show.Pretty(ppShow) main = do s <- getContents - print (BatshLex.scanTokens s) + putStrLn (ppShow $ BatshParser.parse s) diff --git a/test/UnitTest.hs b/test/UnitTest.hs index 93bde9a..d8af9c1 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -3,6 +3,8 @@ import Data.Monoid import Test.HUnit import Test.Framework import Test.Framework.Providers.HUnit + +import Batsh import BatshAst import qualified BatshLex import qualified BatshParser @@ -81,8 +83,21 @@ testParser = do testStatement "if (1) if (2) {true;} else {}" (If (Literal (Int 1), IfElse ( Literal (Int 2), Block [Expression (Literal (Bool True))], Block []))) +testParseFile :: Assertion +testParseFile = do + let testParseFile codeFile astFile = do + expected <- parseFromAstFile astFile + ast <- parseFromFile codeFile + assertEqual (show ast) expected ast + let testCaseDir = "test/testcase" + let testCases = ["arith"] + forM_ testCases $ \testcase -> + testParseFile (testCaseDir ++ "/Batsh/" ++ testcase ++ ".batsh") + (testCaseDir ++ "/BatshAst/" ++ testcase ++ ".parsed") + main :: IO () main = defaultMainWithOpts [testCase "Lexer" testLexer, - testCase "Parser" testParser] + testCase "Parser" testParser, + testCase "ParseFile" testParseFile] mempty diff --git a/test/testcase/Batsh/arith.batsh b/test/testcase/Batsh/arith.batsh new file mode 100644 index 0000000..6607aa7 --- /dev/null +++ b/test/testcase/Batsh/arith.batsh @@ -0,0 +1,16 @@ +println(false); +println(true); +println(42); +println(1 + (4 + 6) * 3); +println(8 - 3 % 2); +println(-9 - 9); +println((2 + 8) / 3); +println(2 === 2); +println(6 !== 8); +println(3 > 2); +println(4 < 5); +println(6 >= 2); +println(19 <= 30); +println(!true); +println(!false); +println(!(2 - 1)); diff --git a/test/testcase/BatshAst/arith.parsed b/test/testcase/BatshAst/arith.parsed new file mode 100644 index 0000000..974fda0 --- /dev/null +++ b/test/testcase/BatshAst/arith.parsed @@ -0,0 +1,102 @@ +[ Statement + (Expression (Call ( "println" , [ Literal (Bool False) ] ))) +, Statement + (Expression (Call ( "println" , [ Literal (Bool True) ] ))) +, Statement + (Expression (Call ( "println" , [ Literal (Int 42) ] ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary + ( Plus + , Literal (Int 1) + , Binary + ( Multiply + , Binary ( Plus , Literal (Int 4) , Literal (Int 6) ) + , Literal (Int 3) + ) + ) + ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary + ( Minus + , Literal (Int 8) + , Binary ( Modulo , Literal (Int 3) , Literal (Int 2) ) + ) + ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary + ( Minus , Unary ( Negate , Literal (Int 9) ) , Literal (Int 9) ) + ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary + ( Divide + , Binary ( Plus , Literal (Int 2) , Literal (Int 8) ) + , Literal (Int 3) + ) + ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary ( ArithEqual , Literal (Int 2) , Literal (Int 2) ) ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary ( ArithNotEqual , Literal (Int 6) , Literal (Int 8) ) ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary ( Greater , Literal (Int 3) , Literal (Int 2) ) ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary ( Less , Literal (Int 4) , Literal (Int 5) ) ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary ( GreaterEqual , Literal (Int 6) , Literal (Int 2) ) ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary ( LessEqual , Literal (Int 19) , Literal (Int 30) ) ] + ))) +, Statement + (Expression + (Call ( "println" , [ Unary ( Not , Literal (Bool True) ) ] ))) +, Statement + (Expression + (Call ( "println" , [ Unary ( Not , Literal (Bool False) ) ] ))) +, Statement + (Expression + (Call + ( "println" + , [ Unary + ( Not , Binary ( Minus , Literal (Int 2) , Literal (Int 1) ) ) + ] + ))) +] From bc29c7a529d2db791a8bf48e5d9674957964aa7e Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Tue, 28 Oct 2014 20:01:07 +0100 Subject: [PATCH 14/53] Reorganize package hierarchy --- batsh.cabal | 6 +- src/Batsh.hs | 6 +- src/{BatshAst.hs => Batsh/Ast.hs} | 2 +- src/{BatshLex.x => Batsh/Lexer.x} | 6 +- src/Batsh/Parser.y | 166 ++++++++++++++++++++++++++++++ src/BatshParser.y | 166 ------------------------------ src/Main.hs | 4 +- test/UnitTest.hs | 98 +++++++++--------- 8 files changed, 227 insertions(+), 227 deletions(-) rename src/{BatshAst.hs => Batsh/Ast.hs} (98%) rename src/{BatshLex.x => Batsh/Lexer.x} (96%) create mode 100644 src/Batsh/Parser.y delete mode 100644 src/BatshParser.y diff --git a/batsh.cabal b/batsh.cabal index 3d265b0..cd06435 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -12,9 +12,9 @@ Build-Type: Simple Library Build-Depends: array, base Exposed-Modules: Batsh, - BatshAst, - BatshLex, - BatshParser + Batsh.Ast, + Batsh.Lexer, + Batsh.Parser Hs-Source-Dirs: src Executable batsh diff --git a/src/Batsh.hs b/src/Batsh.hs index ff1ce96..6bdc2e9 100644 --- a/src/Batsh.hs +++ b/src/Batsh.hs @@ -1,12 +1,12 @@ module Batsh where -import BatshAst -import qualified BatshParser +import Batsh.Ast +import qualified Batsh.Parser parseFromFile :: FilePath -> IO Program parseFromFile path = do code <- readFile path - return (BatshParser.parse code) + return (Batsh.Parser.parse code) parseFromAstFile :: FilePath -> IO Program parseFromAstFile path = do diff --git a/src/BatshAst.hs b/src/Batsh/Ast.hs similarity index 98% rename from src/BatshAst.hs rename to src/Batsh/Ast.hs index 9e59be8..2de999d 100644 --- a/src/BatshAst.hs +++ b/src/Batsh/Ast.hs @@ -1,4 +1,4 @@ -module BatshAst where +module Batsh.Ast where data Literal = Bool Bool | Int Int diff --git a/src/BatshLex.x b/src/Batsh/Lexer.x similarity index 96% rename from src/BatshLex.x rename to src/Batsh/Lexer.x index df75a84..7c01bcc 100644 --- a/src/BatshLex.x +++ b/src/Batsh/Lexer.x @@ -2,7 +2,7 @@ -- Rules are inspired by Haskell alex examples/haskell.x { -module BatshLex where +module Batsh.Lexer where } %wrapper "basic" @@ -47,8 +47,8 @@ tokens :- @hexadecimal{ \s -> Int (read s) } @float { \s -> Float (read s) } @string { \s -> String (tail $ init s) } - "true" { \s -> BatshLex.True } - "false" { \s -> BatshLex.False } + "true" { \s -> Batsh.Lexer.True } + "false" { \s -> Batsh.Lexer.False } "if" { \s -> If } "else" { \s -> Else } "while" { \s -> While } diff --git a/src/Batsh/Parser.y b/src/Batsh/Parser.y new file mode 100644 index 0000000..858f222 --- /dev/null +++ b/src/Batsh/Parser.y @@ -0,0 +1,166 @@ +-- This file includes the parsing rules of Batsh. + +{ +module Batsh.Parser(parse, + parseTopLevel, + parseStatement, + parseExpression) where + +import qualified Batsh.Ast as Ast +import qualified Batsh.Lexer as Lexer +} + +-- parse function terminal name +%name program program +%name toplevel toplevel +%name statement statement +%name expression expression + +%tokentype { Lexer.Token } +%error { parseError } + +%token + int { Lexer.Int $$ } + float { Lexer.Float $$ } + string { Lexer.String $$ } + true { Lexer.True } + false { Lexer.False } + if { Lexer.If } + else { Lexer.Else } + while { Lexer.While } + function { Lexer.Function } + global { Lexer.Global } + return { Lexer.Return } + '!' { Lexer.Not } + ';' { Lexer.Semicolon } + ',' { Lexer.Comma } + '+' { Lexer.Plus } + '-' { Lexer.Minus } + '*' { Lexer.Multiply } + '/' { Lexer.Divide } + '%' { Lexer.Modulo } + '++' { Lexer.Concat } + '=' { Lexer.Assign } + '==' { Lexer.Equal } + '!=' { Lexer.NotEqual } + '===' { Lexer.ArithEqual } + '!==' { Lexer.ArithNotEqual } + '>' { Lexer.Greater } + '<' { Lexer.Less } + '>=' { Lexer.GreaterEqual } + '<=' { Lexer.LessEqual } + '&&' { Lexer.And } + '||' { Lexer.Or } + '(' { Lexer.LParen } + ')' { Lexer.RParen } + '[' { Lexer.LBrack } + ']' { Lexer.RBrack } + '{' { Lexer.LBrace } + '}' { Lexer.RBrace } + comment { Lexer.Comment $$ } + ident { Lexer.Identifier $$ } + +%right if else +%right '=' +%left '||' +%left '&&' +%nonassoc '==' '!=' '===' '!==' +%nonassoc '>' '<' '>=' '<=' +%left '++' +%left '+' '-' +%left '*' '/' '%' +%nonassoc '!' '-' + +%% + +program : toplevels { $1 } + +toplevel : statement { Ast.Statement $1 } + | function ident '(' idents ')' + '{' statements '}' { Ast.Function ($2, $4, $7)} + +statement : comment { Ast.Comment $1 } + | '{' statements '}' { Ast.Block $2 } + | expression ';' { Ast.Expression $1 } + | global ident ';' { Ast.Global $2 } + | return expression ';' { Ast.Return $ Just $2 } + | return ';' { Ast.Return $ Nothing } + | if_statement { $1 } + | loop_statement { $1 } + +if_statement : if '(' expression ')' + statement %prec if { Ast.If ($3, $5) } + | if '(' expression ')' + statement else statement { Ast.IfElse ($3, $5, $7) } + +loop_statement: while '(' expression ')' + statement { Ast.While ($3, $5) } + +expression : leftvalue { Ast.LeftValue $1 } + | literal { Ast.Literal $1 } + | ident '(' expressions ')' { Ast.Call ($1, $3) } + | '(' expression ')' { $2 } + | unary { Ast.Unary $1 } + | binary { Ast.Binary $1 } + | leftvalue '=' expression { Ast.Assign ($1, $3) } + +unary : '!' expression { Ast.Not, $2 } + | '-' expression %prec '-' { Ast.Negate, $2 } + +binary : expression '+' expression { Ast.Plus, $1, $3 } + | expression '-' expression { Ast.Minus, $1, $3 } + | expression '*' expression { Ast.Multiply, $1, $3 } + | expression '/' expression { Ast.Divide, $1, $3 } + | expression '%' expression { Ast.Modulo, $1, $3 } + | expression '++' expression { Ast.Concat, $1, $3 } + | expression '==' expression { Ast.Equal, $1, $3 } + | expression '!=' expression { Ast.NotEqual, $1, $3 } + | expression '===' expression { Ast.ArithEqual, $1, $3 } + | expression '!==' expression { Ast.ArithNotEqual, $1, $3 } + | expression '>' expression { Ast.Greater, $1, $3 } + | expression '<' expression { Ast.Less, $1, $3 } + | expression '>=' expression { Ast.GreaterEqual, $1, $3 } + | expression '<=' expression { Ast.LessEqual, $1, $3 } + | expression '&&' expression { Ast.And, $1, $3 } + | expression '||' expression { Ast.Or, $1, $3 } + +literal : true { Ast.Bool True } + | false { Ast.Bool False } + | int { Ast.Int $1 } + | float { Ast.Float $1 } + | string { Ast.String $1 } + | '[' expressions ']' { Ast.List $2 } + +leftvalue : ident { Ast.Identifier $1 } + | leftvalue '[' expression ']' { Ast.ListAccess ($1, $3) } + +toplevels : { [] } + | toplevel toplevels { $1 : $2 } + +statements : { [] } + | statement statements { $1 : $2 } + +expressions : { [] } + | expression { [$1] } + | expression ',' expressions { $1 : $3 } + +idents : { [] } + | ident { [$1] } + | ident ',' idents { $1 : $3 } + +{ +parseError :: [Lexer.Token] -> a +parseError _ = error "Parse error" + +parse :: String -> Ast.Program +parse = program . Lexer.scanTokens + +parseTopLevel :: String -> Ast.TopLevel +parseTopLevel = toplevel . Lexer.scanTokens + +parseStatement :: String -> Ast.Statement +parseStatement = statement . Lexer.scanTokens + +parseExpression :: String -> Ast.Expression +parseExpression = expression . Lexer.scanTokens +} diff --git a/src/BatshParser.y b/src/BatshParser.y deleted file mode 100644 index 5f275b8..0000000 --- a/src/BatshParser.y +++ /dev/null @@ -1,166 +0,0 @@ --- This file includes the parsing rules of Batsh. - -{ -module BatshParser(parse, - parseTopLevel, - parseStatement, - parseExpression) where - -import qualified BatshAst -import qualified BatshLex -} - --- parse function terminal name -%name program program -%name toplevel toplevel -%name statement statement -%name expression expression - -%tokentype { BatshLex.Token } -%error { parseError } - -%token - int { BatshLex.Int $$ } - float { BatshLex.Float $$ } - string { BatshLex.String $$ } - true { BatshLex.True } - false { BatshLex.False } - if { BatshLex.If } - else { BatshLex.Else } - while { BatshLex.While } - function { BatshLex.Function } - global { BatshLex.Global } - return { BatshLex.Return } - '!' { BatshLex.Not } - ';' { BatshLex.Semicolon } - ',' { BatshLex.Comma } - '+' { BatshLex.Plus } - '-' { BatshLex.Minus } - '*' { BatshLex.Multiply } - '/' { BatshLex.Divide } - '%' { BatshLex.Modulo } - '++' { BatshLex.Concat } - '=' { BatshLex.Assign } - '==' { BatshLex.Equal } - '!=' { BatshLex.NotEqual } - '===' { BatshLex.ArithEqual } - '!==' { BatshLex.ArithNotEqual } - '>' { BatshLex.Greater } - '<' { BatshLex.Less } - '>=' { BatshLex.GreaterEqual } - '<=' { BatshLex.LessEqual } - '&&' { BatshLex.And } - '||' { BatshLex.Or } - '(' { BatshLex.LParen } - ')' { BatshLex.RParen } - '[' { BatshLex.LBrack } - ']' { BatshLex.RBrack } - '{' { BatshLex.LBrace } - '}' { BatshLex.RBrace } - comment { BatshLex.Comment $$ } - ident { BatshLex.Identifier $$ } - -%right if else -%right '=' -%left '||' -%left '&&' -%nonassoc '==' '!=' '===' '!==' -%nonassoc '>' '<' '>=' '<=' -%left '++' -%left '+' '-' -%left '*' '/' '%' -%nonassoc '!' '-' - -%% - -program : toplevels { $1 } - -toplevel : statement { BatshAst.Statement $1 } - | function ident '(' idents ')' - '{' statements '}' { BatshAst.Function ($2, $4, $7)} - -statement : comment { BatshAst.Comment $1 } - | '{' statements '}' { BatshAst.Block $2 } - | expression ';' { BatshAst.Expression $1 } - | global ident ';' { BatshAst.Global $2 } - | return expression ';' { BatshAst.Return $ Just $2 } - | return ';' { BatshAst.Return $ Nothing } - | if_statement { $1 } - | loop_statement { $1 } - -if_statement : if '(' expression ')' - statement %prec if { BatshAst.If ($3, $5) } - | if '(' expression ')' - statement else statement { BatshAst.IfElse ($3, $5, $7) } - -loop_statement: while '(' expression ')' - statement { BatshAst.While ($3, $5) } - -expression : leftvalue { BatshAst.LeftValue $1 } - | literal { BatshAst.Literal $1 } - | ident '(' expressions ')' { BatshAst.Call ($1, $3) } - | '(' expression ')' { $2 } - | unary { BatshAst.Unary $1 } - | binary { BatshAst.Binary $1 } - | leftvalue '=' expression { BatshAst.Assign ($1, $3) } - -unary : '!' expression { BatshAst.Not, $2 } - | '-' expression %prec '-' { BatshAst.Negate, $2 } - -binary : expression '+' expression { BatshAst.Plus, $1, $3 } - | expression '-' expression { BatshAst.Minus, $1, $3 } - | expression '*' expression { BatshAst.Multiply, $1, $3 } - | expression '/' expression { BatshAst.Divide, $1, $3 } - | expression '%' expression { BatshAst.Modulo, $1, $3 } - | expression '++' expression { BatshAst.Concat, $1, $3 } - | expression '==' expression { BatshAst.Equal, $1, $3 } - | expression '!=' expression { BatshAst.NotEqual, $1, $3 } - | expression '===' expression { BatshAst.ArithEqual, $1, $3 } - | expression '!==' expression { BatshAst.ArithNotEqual, $1, $3 } - | expression '>' expression { BatshAst.Greater, $1, $3 } - | expression '<' expression { BatshAst.Less, $1, $3 } - | expression '>=' expression { BatshAst.GreaterEqual, $1, $3 } - | expression '<=' expression { BatshAst.LessEqual, $1, $3 } - | expression '&&' expression { BatshAst.And, $1, $3 } - | expression '||' expression { BatshAst.Or, $1, $3 } - -literal : true { BatshAst.Bool True } - | false { BatshAst.Bool False } - | int { BatshAst.Int $1 } - | float { BatshAst.Float $1 } - | string { BatshAst.String $1 } - | '[' expressions ']' { BatshAst.List $2 } - -leftvalue : ident { BatshAst.Identifier $1 } - | leftvalue '[' expression ']' { BatshAst.ListAccess ($1, $3) } - -toplevels : { [] } - | toplevel toplevels { $1 : $2 } - -statements : { [] } - | statement statements { $1 : $2 } - -expressions : { [] } - | expression { [$1] } - | expression ',' expressions { $1 : $3 } - -idents : { [] } - | ident { [$1] } - | ident ',' idents { $1 : $3 } - -{ -parseError :: [BatshLex.Token] -> a -parseError _ = error "Parse error" - -parse :: String -> BatshAst.Program -parse = program . BatshLex.scanTokens - -parseTopLevel :: String -> BatshAst.TopLevel -parseTopLevel = toplevel . BatshLex.scanTokens - -parseStatement :: String -> BatshAst.Statement -parseStatement = statement . BatshLex.scanTokens - -parseExpression :: String -> BatshAst.Expression -parseExpression = expression . BatshLex.scanTokens -} diff --git a/src/Main.hs b/src/Main.hs index 1106697..0b28be8 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,6 +1,6 @@ -import qualified BatshParser +import qualified Batsh.Parser import Text.Show.Pretty(ppShow) main = do s <- getContents - putStrLn (ppShow $ BatshParser.parse s) + putStrLn (ppShow $ Batsh.Parser.parse s) diff --git a/test/UnitTest.hs b/test/UnitTest.hs index d8af9c1..2bd3404 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -5,58 +5,58 @@ import Test.Framework import Test.Framework.Providers.HUnit import Batsh -import BatshAst -import qualified BatshLex -import qualified BatshParser +import Batsh.Ast +import qualified Batsh.Lexer as Lexer +import qualified Batsh.Parser testLexer :: Assertion testLexer = do let testSingle str expected = do - let tokens = BatshLex.alexScanTokens str + let tokens = Lexer.scanTokens str let token = head tokens assertEqual "Number of tokens" 1 (length tokens) assertEqual (show token) expected token - testSingle "variable" $ BatshLex.Identifier "variable" - testSingle "//a line comment" $ BatshLex.Comment "a line comment" - testSingle "42" $ BatshLex.Int 42 - testSingle "0xFF" $ BatshLex.Int 255 - testSingle "3.14" $ BatshLex.Float 3.14 - testSingle "1E-8" $ BatshLex.Float 1e-8 - testSingle "\"string\\n\"" $ BatshLex.String "string\\n" - testSingle "true" BatshLex.True - testSingle "false" BatshLex.False - testSingle "if" BatshLex.If - testSingle "else" BatshLex.Else - testSingle "while" BatshLex.While - testSingle "function" BatshLex.Function - testSingle "global" BatshLex.Global - testSingle "return" BatshLex.Return - testSingle "!" BatshLex.Not - testSingle ";" BatshLex.Semicolon - testSingle "," BatshLex.Comma - testSingle "+" BatshLex.Plus - testSingle "-" BatshLex.Minus - testSingle "*" BatshLex.Multiply - testSingle "/" BatshLex.Divide - testSingle "%" BatshLex.Modulo - testSingle "++" BatshLex.Concat - testSingle "=" BatshLex.Assign - testSingle "==" BatshLex.Equal - testSingle "!=" BatshLex.NotEqual - testSingle "===" BatshLex.ArithEqual - testSingle "!==" BatshLex.ArithNotEqual - testSingle ">" BatshLex.Greater - testSingle "<" BatshLex.Less - testSingle ">=" BatshLex.GreaterEqual - testSingle "<=" BatshLex.LessEqual - testSingle "&&" BatshLex.And - testSingle "||" BatshLex.Or - testSingle "(" BatshLex.LParen - testSingle ")" BatshLex.RParen - testSingle "[" BatshLex.LBrack - testSingle "]" BatshLex.RBrack - testSingle "{" BatshLex.LBrace - testSingle "}" BatshLex.RBrace + testSingle "variable" $ Lexer.Identifier "variable" + testSingle "//a line comment" $ Lexer.Comment "a line comment" + testSingle "42" $ Lexer.Int 42 + testSingle "0xFF" $ Lexer.Int 255 + testSingle "3.14" $ Lexer.Float 3.14 + testSingle "1E-8" $ Lexer.Float 1e-8 + testSingle "\"string\\n\"" $ Lexer.String "string\\n" + testSingle "true" Lexer.True + testSingle "false" Lexer.False + testSingle "if" Lexer.If + testSingle "else" Lexer.Else + testSingle "while" Lexer.While + testSingle "function" Lexer.Function + testSingle "global" Lexer.Global + testSingle "return" Lexer.Return + testSingle "!" Lexer.Not + testSingle ";" Lexer.Semicolon + testSingle "," Lexer.Comma + testSingle "+" Lexer.Plus + testSingle "-" Lexer.Minus + testSingle "*" Lexer.Multiply + testSingle "/" Lexer.Divide + testSingle "%" Lexer.Modulo + testSingle "++" Lexer.Concat + testSingle "=" Lexer.Assign + testSingle "==" Lexer.Equal + testSingle "!=" Lexer.NotEqual + testSingle "===" Lexer.ArithEqual + testSingle "!==" Lexer.ArithNotEqual + testSingle ">" Lexer.Greater + testSingle "<" Lexer.Less + testSingle ">=" Lexer.GreaterEqual + testSingle "<=" Lexer.LessEqual + testSingle "&&" Lexer.And + testSingle "||" Lexer.Or + testSingle "(" Lexer.LParen + testSingle ")" Lexer.RParen + testSingle "[" Lexer.LBrack + testSingle "]" Lexer.RBrack + testSingle "{" Lexer.LBrace + testSingle "}" Lexer.RBrace testParser :: Assertion testParser = do @@ -64,10 +64,10 @@ testParser = do testAst parser code expected = assertEqual (show ast) expected ast where ast = parser code - let testProgram = testAst BatshParser.parse - let testTopLevel = testAst BatshParser.parseTopLevel - let testStatement = testAst BatshParser.parseStatement - let testExpression = testAst BatshParser.parseExpression + let testProgram = testAst Batsh.Parser.parse + let testTopLevel = testAst Batsh.Parser.parseTopLevel + let testStatement = testAst Batsh.Parser.parseStatement + let testExpression = testAst Batsh.Parser.parseExpression -- Expression testExpression "3" (Literal $ Int 3) testExpression "[4.2 + 3, \"str\", []]" (Literal $ List [Binary (Plus, From 65c2b9fdd71e5cdf188b0907cf41ef066bb09a1a Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Wed, 29 Oct 2014 19:49:14 +0100 Subject: [PATCH 15/53] Code generation (Batsh formatter) --- batsh.cabal | 5 +- src/Batsh/Ast.hs | 8 +-- src/Batsh/Generator.hs | 143 +++++++++++++++++++++++++++++++++++++++++ test/UnitTest.hs | 11 +++- 4 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 src/Batsh/Generator.hs diff --git a/batsh.cabal b/batsh.cabal index cd06435..215e5db 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -10,9 +10,10 @@ Synopsis: A language that compiles to Bash and Windows Batch Build-Type: Simple Library - Build-Depends: array, base + Build-Depends: array, base, bytestring Exposed-Modules: Batsh, Batsh.Ast, + Batsh.Generator, Batsh.Lexer, Batsh.Parser Hs-Source-Dirs: src @@ -20,7 +21,7 @@ Library Executable batsh Main-Is: Main.hs Hs-Source-Dirs: src - Build-Depends: array, base, Batsh, pretty-show + Build-Depends: array, base, bytestring, Batsh, pretty-show Test-Suite unit-test Type: exitcode-stdio-1.0 diff --git a/src/Batsh/Ast.hs b/src/Batsh/Ast.hs index 2de999d..dcad3b6 100644 --- a/src/Batsh/Ast.hs +++ b/src/Batsh/Ast.hs @@ -9,6 +9,10 @@ data Literal = Bool Bool type Identifier = String +data LeftValue = Identifier Identifier + | ListAccess (LeftValue, Expression) + deriving (Eq,Read,Show) + data UnaryOperator = Not | Negate deriving (Eq,Read,Show) @@ -17,10 +21,6 @@ data BinaryOperator = Plus | Minus | Multiply | Divide | Modulo | Concat | GreaterEqual | LessEqual | And | Or deriving (Eq,Read,Show) -data LeftValue = Identifier Identifier - | ListAccess (LeftValue, Expression) - deriving (Eq,Read,Show) - data Expression = LeftValue LeftValue | Literal Literal | Unary (UnaryOperator, Expression) diff --git a/src/Batsh/Generator.hs b/src/Batsh/Generator.hs new file mode 100644 index 0000000..96d9b12 --- /dev/null +++ b/src/Batsh/Generator.hs @@ -0,0 +1,143 @@ +module Batsh.Generator where + +import qualified Data.ByteString +import Data.ByteString.Lazy(ByteString, putStr) +import Data.Monoid +import Data.ByteString.Builder(Builder, + charUtf8, + floatDec, + intDec, + stringUtf8, + toLazyByteString) +import Data.Word + +import Batsh.Ast + +renderLiteral :: Literal -> Builder +renderLiteral literal = case literal of + Int num -> intDec num + Float num -> floatDec num + String str -> mconcat [charUtf8 '"', + stringUtf8 str, + charUtf8 '"'] + Bool bool -> case bool of + True -> stringUtf8 "true" + False -> stringUtf8 "false" + List list -> mconcat [stringUtf8 "[", + renderExpressions list, + stringUtf8 "]"] + +renderLeftValue :: LeftValue -> Builder +renderLeftValue lvalue = case lvalue of + Identifier ident -> stringUtf8 ident + ListAccess (lvalue, expr) -> mconcat [renderLeftValue lvalue, + stringUtf8 "[", + renderExpression expr, + stringUtf8 "]"] + +renderUnary :: (UnaryOperator, Expression) -> Builder +renderUnary (operator, expr) = + mconcat [charUtf8 operatorString, renderExpression expr] + where operatorString = + case operator of + Not -> '!' + Negate -> '-' + +renderBinary :: (BinaryOperator, Expression, Expression) -> Builder +renderBinary (operator, left, right) = + mconcat [renderExpression left, + stringUtf8 operatorString, + renderExpression right] + where operatorString = + case operator of + Plus -> "+" + Minus -> "-" + Multiply -> "*" + Divide -> "/" + Modulo -> "%" + Concat -> "++" + Equal -> "==" + NotEqual -> "!=" + ArithEqual -> "===" + ArithNotEqual -> "!==" + Greater -> ">" + Less -> "<" + GreaterEqual -> ">=" + LessEqual -> "<=" + And -> "&&" + Or -> "||" + +renderExpression :: Expression -> Builder +renderExpression expr = case expr of + LeftValue lvalue -> renderLeftValue lvalue + Literal literal -> renderLiteral literal + Unary unary -> renderUnary unary + Binary binary -> renderBinary binary + Assign (lvalue, expr) -> mconcat [renderLeftValue lvalue, + stringUtf8 " = ", + renderExpression expr] + Call (ident, exprs) -> mconcat [stringUtf8 ident, + charUtf8 '(', + renderExpressions exprs, + charUtf8 ')'] + +renderSeparateList :: [a] -> String -> (a -> Builder) -> Builder +renderSeparateList list separator renderer = case list of + [] -> mempty + [elem] -> renderer elem + (elem : rest) -> mconcat [renderer elem, + stringUtf8 separator, + renderSeparateList rest separator renderer] + +renderExpressions :: [Expression] -> Builder +renderExpressions exprs = renderSeparateList exprs ", " renderExpression + +renderBlock :: [Statement] -> Word -> Builder +renderBlock stmts level = mconcat + [stringUtf8 "{", + mconcat $ map (\stmt-> renderStatementIndent stmt $ level + 2) stmts, + stringUtf8 "}" + ] + +renderStatementIndent :: Statement -> Word -> Builder +renderStatementIndent stmt level = case stmt of + Comment comment -> mconcat [stringUtf8 "// ", + stringUtf8 comment] + Block stmts -> renderBlock stmts level + Expression expr -> withSemicolon $ renderExpression expr + If (expr, stmt) -> mconcat [stringUtf8 "if (", + renderExpression expr, + stringUtf8 ") ", + renderStatement stmt] + IfElse (expr, thenStmt, elseStmt) -> mconcat [stringUtf8 "if (", + renderExpression expr, + stringUtf8 ") ", + renderStatement thenStmt, + stringUtf8 " else ", + renderStatement elseStmt] + While (expr, stmt) -> mconcat [stringUtf8 "while (", + renderExpression expr, + stringUtf8 ") ", + renderStatement stmt] + Global ident -> withSemicolon $ stringUtf8 ident + Return (Just expr) -> withSemicolon $ mconcat [stringUtf8 "return ", + renderExpression expr] + Return Nothing -> withSemicolon $ stringUtf8 "return" + where withSemicolon builder = mconcat [builder, charUtf8 ';'] + +renderStatement :: Statement -> Builder +renderStatement stmt = renderStatementIndent stmt (0 :: Word) + +renderTopLevel :: TopLevel -> Builder +renderTopLevel toplevel = case toplevel of + Statement stmt -> renderStatement stmt + +renderProgram :: Program -> Builder +renderProgram program = renderSeparateList program ", " renderTopLevel + +printToByteString :: Program -> ByteString +printToByteString program = toLazyByteString $ renderProgram program + +print :: Program -> IO () +print program = + Data.ByteString.Lazy.putStr $ printToByteString program diff --git a/test/UnitTest.hs b/test/UnitTest.hs index 2bd3404..f2c96dd 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -6,6 +6,7 @@ import Test.Framework.Providers.HUnit import Batsh import Batsh.Ast +import qualified Batsh.Generator import qualified Batsh.Lexer as Lexer import qualified Batsh.Parser @@ -95,9 +96,17 @@ testParseFile = do testParseFile (testCaseDir ++ "/Batsh/" ++ testcase ++ ".batsh") (testCaseDir ++ "/BatshAst/" ++ testcase ++ ".parsed") +testGenerator :: Assertion +testGenerator = do + --let bs = Batsh.Generator.print $ List [Literal $ Int 3, LeftValue $ ListAccess (Identifier "a", Literal $ Int 3)] + --show bs + --assertEqual (show bs) True False + return () + main :: IO () main = defaultMainWithOpts [testCase "Lexer" testLexer, testCase "Parser" testParser, - testCase "ParseFile" testParseFile] + testCase "ParseFile" testParseFile, + testCase "Generator" testGenerator] mempty From 0350d9603bf050d468305a1f837fc1d305e961b2 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Thu, 30 Oct 2014 19:57:38 +0100 Subject: [PATCH 16/53] Command line parser --- Makefile | 2 +- batsh.cabal | 7 +++- src/Batsh.hs | 17 +++++--- src/Main.hs | 110 +++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 126 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 5cc3705..27560d5 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ test: dist: cabal configure --enable-tests -dist/build/batsh/batsh: dist src/*.hs src/BatshLex.x +dist/build/batsh/batsh: dist cabal build .PHONY: clean test diff --git a/batsh.cabal b/batsh.cabal index 215e5db..60390d8 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -21,7 +21,12 @@ Library Executable batsh Main-Is: Main.hs Hs-Source-Dirs: src - Build-Depends: array, base, bytestring, Batsh, pretty-show + Other-Modules: Batsh, + Batsh.Ast, + Batsh.Generator, + Batsh.Lexer, + Batsh.Parser + Build-Depends: array, base, bytestring, optparse-applicative >= 0.11.0.1, pretty-show Test-Suite unit-test Type: exitcode-stdio-1.0 diff --git a/src/Batsh.hs b/src/Batsh.hs index 6bdc2e9..f01e08f 100644 --- a/src/Batsh.hs +++ b/src/Batsh.hs @@ -1,14 +1,21 @@ module Batsh where -import Batsh.Ast +import qualified Batsh.Ast +import qualified Batsh.Lexer import qualified Batsh.Parser -parseFromFile :: FilePath -> IO Program +lex :: String -> [Batsh.Lexer.Token] +lex code = Batsh.Lexer.scanTokens code + +parse :: String -> Batsh.Ast.Program +parse code = Batsh.Parser.parse code + +parseFromFile :: FilePath -> IO Batsh.Ast.Program parseFromFile path = do code <- readFile path - return (Batsh.Parser.parse code) + return $ parse code -parseFromAstFile :: FilePath -> IO Program +parseFromAstFile :: FilePath -> IO Batsh.Ast.Program parseFromAstFile path = do code <- readFile path - return (read code :: Program) + return (read code :: Batsh.Ast.Program) diff --git a/src/Main.hs b/src/Main.hs index 0b28be8..71f4d84 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,6 +1,110 @@ -import qualified Batsh.Parser +{-# LANGUAGE Arrows #-} + +import Control.Monad +import Options.Applicative +import Options.Applicative.Arrows import Text.Show.Pretty(ppShow) +import qualified Batsh + +data Args = Args CommonOpts Command + deriving Show + +data CommonOpts = CommonOpts + { optVerbosity :: Int } + deriving Show + +data Command + = Batsh FilePath FilePath BatshOpts + | Bash + | Winbat + deriving Show + +data BatshOpts = BatshOpts + { ast :: Bool, + tokens :: Bool, + symbols :: Bool } + deriving Show + +version :: Parser (a -> a) +version = infoOption "0.1.0" + ( long "version" + <> short 'v' + <> help "Print version information" ) + +parser :: Parser Args +parser = runA $ proc () -> do + opts <- asA commonOpts -< () + cmds <- (asA . hsubparser) + ( command "batsh" + (info batshParser + (progDesc "Format Batsh code")) + <> command "bash" + (info bashParser + (progDesc "Compile to Bash")) + <> command "winbat" + (info winbatParser + (progDesc "Compile to Windows Batch")) + ) -< () + A version >>> A helper -< Args opts cmds + +commonOpts :: Parser CommonOpts +commonOpts = CommonOpts + <$> option auto + ( long "verbose" + <> metavar "LEVEL" + <> help "Set verbosity to LEVEL" + <> value 0 ) + +batshParser :: Parser Command +batshParser = runA $ proc () -> do + input <- asA (strArgument (metavar "INPUT" + <> help "Source code file")) -< () + output <- asA (strArgument (metavar "TARGET" + <> help "Target file")) -< () + opts <- asA batshOpts -< () + returnA -< Batsh input output opts + +batshOpts :: Parser BatshOpts +batshOpts = runA $ proc () -> do + ast <- asA (switch (long "ast" + <> help "Output parsed abstract syntax tree")) -< () + tokens <- asA (switch (long "tokens" + <> help "Output parsed tokens")) -< () + symbols <- asA (switch (long "symbols" + <> help "Output symbol table")) -< () + returnA -< BatshOpts { + ast = ast, + tokens = tokens, + symbols = symbols} + +bashParser :: Parser Command +bashParser = pure Bash + +winbatParser :: Parser Command +winbatParser = pure Winbat + +dispatch :: Args -> IO () +dispatch (Args opts cmd) = case cmd of + Batsh input target opts -> batsh input target opts + +batsh :: FilePath -> FilePath -> BatshOpts -> IO () +batsh input target opts = do + code <- readFile input + let outputWithSuffix :: String -> String -> IO (); + outputWithSuffix suffix contents = do + let fileName = target ++ suffix + writeFile fileName contents + when (tokens opts) (outputWithSuffix ".tokens" (ppShow $ Batsh.lex code)) + when (ast opts) (outputWithSuffix ".ast" (ppShow $ Batsh.parse code)) + -- TODO symbols + return () + +pinfo :: ParserInfo Args +pinfo = info parser $ + progDesc "A language that compiles to Bash and Windows Batch" + +main :: IO () main = do - s <- getContents - putStrLn (ppShow $ Batsh.Parser.parse s) + args <- execParser pinfo + dispatch args From 8014a96cd60e7c2642de93dfdac934cd89bbe1ce Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Thu, 30 Oct 2014 20:39:08 +0100 Subject: [PATCH 17/53] Code generation in command line --- src/Batsh.hs | 4 ++++ src/Batsh/Generator.hs | 20 ++++++++++++++------ src/Main.hs | 19 +++++++++++-------- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/Batsh.hs b/src/Batsh.hs index f01e08f..15a387c 100644 --- a/src/Batsh.hs +++ b/src/Batsh.hs @@ -1,6 +1,7 @@ module Batsh where import qualified Batsh.Ast +import qualified Batsh.Generator import qualified Batsh.Lexer import qualified Batsh.Parser @@ -19,3 +20,6 @@ parseFromAstFile :: FilePath -> IO Batsh.Ast.Program parseFromAstFile path = do code <- readFile path return (read code :: Batsh.Ast.Program) + +generateCodeToFile :: Batsh.Ast.Program -> FilePath -> IO () +generateCodeToFile = Batsh.Generator.printToFile diff --git a/src/Batsh/Generator.hs b/src/Batsh/Generator.hs index 96d9b12..033d940 100644 --- a/src/Batsh/Generator.hs +++ b/src/Batsh/Generator.hs @@ -1,7 +1,7 @@ module Batsh.Generator where import qualified Data.ByteString -import Data.ByteString.Lazy(ByteString, putStr) +import Data.ByteString.Lazy(ByteString, putStr, writeFile) import Data.Monoid import Data.ByteString.Builder(Builder, charUtf8, @@ -135,9 +135,17 @@ renderTopLevel toplevel = case toplevel of renderProgram :: Program -> Builder renderProgram program = renderSeparateList program ", " renderTopLevel -printToByteString :: Program -> ByteString -printToByteString program = toLazyByteString $ renderProgram program +generateByteString :: Program -> ByteString +generateByteString program = toLazyByteString $ renderProgram program -print :: Program -> IO () -print program = - Data.ByteString.Lazy.putStr $ printToByteString program +generateString :: Program -> String +generateString = show . generateByteString + +printToStdout :: Program -> IO () +printToStdout program = do + Data.ByteString.Lazy.putStr $ generateByteString program + putChar '\n' + +printToFile :: Program -> FilePath -> IO () +printToFile program filename = Data.ByteString.Lazy.writeFile filename code + where code = generateByteString program diff --git a/src/Main.hs b/src/Main.hs index 71f4d84..5bbd86f 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -21,9 +21,9 @@ data Command deriving Show data BatshOpts = BatshOpts - { ast :: Bool, - tokens :: Bool, - symbols :: Bool } + { batshOptsAst :: Bool, + batshOptsTokens :: Bool, + batshOptsSymbols :: Bool } deriving Show version :: Parser (a -> a) @@ -74,9 +74,9 @@ batshOpts = runA $ proc () -> do symbols <- asA (switch (long "symbols" <> help "Output symbol table")) -< () returnA -< BatshOpts { - ast = ast, - tokens = tokens, - symbols = symbols} + batshOptsAst = ast, + batshOptsTokens = tokens, + batshOptsSymbols = symbols} bashParser :: Parser Command bashParser = pure Bash @@ -91,13 +91,16 @@ dispatch (Args opts cmd) = case cmd of batsh :: FilePath -> FilePath -> BatshOpts -> IO () batsh input target opts = do code <- readFile input + let program = Batsh.parse code + let tokens = Batsh.lex code let outputWithSuffix :: String -> String -> IO (); outputWithSuffix suffix contents = do let fileName = target ++ suffix writeFile fileName contents - when (tokens opts) (outputWithSuffix ".tokens" (ppShow $ Batsh.lex code)) - when (ast opts) (outputWithSuffix ".ast" (ppShow $ Batsh.parse code)) + when (batshOptsTokens opts) (outputWithSuffix ".tokens" (ppShow tokens)) + when (batshOptsAst opts) (outputWithSuffix ".ast" (ppShow program)) -- TODO symbols + Batsh.generateCodeToFile program target return () pinfo :: ParserInfo Args From 55455a6e12f90584fb9472437db488d1dccb33fc Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Thu, 30 Oct 2014 21:43:43 +0100 Subject: [PATCH 18/53] Define operator precedences in order to reduce parentheses --- src/Batsh/Ast.hs | 27 +++++++++++++++++++++++++++ src/Batsh/Generator.hs | 28 ++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/Batsh/Ast.hs b/src/Batsh/Ast.hs index dcad3b6..ed3ccc5 100644 --- a/src/Batsh/Ast.hs +++ b/src/Batsh/Ast.hs @@ -1,5 +1,8 @@ module Batsh.Ast where +class Operator a where + precedence :: a -> Int + data Literal = Bool Bool | Int Int | Float Float @@ -21,6 +24,30 @@ data BinaryOperator = Plus | Minus | Multiply | Divide | Modulo | Concat | GreaterEqual | LessEqual | And | Or deriving (Eq,Read,Show) +instance Operator BinaryOperator where + precedence operator = case operator of + Or -> 0 + And -> 1 + Equal -> 2 + NotEqual -> 2 + ArithEqual -> 2 + ArithNotEqual -> 2 + Greater -> 3 + Less -> 3 + GreaterEqual -> 3 + LessEqual -> 3 + Concat -> 4 + Plus -> 5 + Minus -> 5 + Multiply -> 6 + Divide -> 6 + Modulo -> 6 + +instance Operator UnaryOperator where + precedence operator = case operator of + Negate -> 7 + Not -> 7 + data Expression = LeftValue LeftValue | Literal Literal | Unary (UnaryOperator, Expression) diff --git a/src/Batsh/Generator.hs b/src/Batsh/Generator.hs index 033d940..195a45f 100644 --- a/src/Batsh/Generator.hs +++ b/src/Batsh/Generator.hs @@ -35,9 +35,23 @@ renderLeftValue lvalue = case lvalue of renderExpression expr, stringUtf8 "]"] +-- Render a subexpression. Add parenthesis if and only if necessary. +renderSubExpression :: (Operator a) => a -> Expression -> Builder +renderSubExpression operator subExpr = + let rendered = renderExpression subExpr in + let renderedWithParen = mconcat [charUtf8 '(', rendered, charUtf8 ')'] in + case subExpr of + -- if subexpression is a binary expression and the precedence of operator is + -- lower, then add (). E.g. + is less precedent than *. + Binary (subOperator, _, _) | precedence subOperator < precedence operator -> + renderedWithParen + Unary (subOperator, _) | precedence subOperator < precedence operator -> + renderedWithParen + _ -> rendered + renderUnary :: (UnaryOperator, Expression) -> Builder renderUnary (operator, expr) = - mconcat [charUtf8 operatorString, renderExpression expr] + mconcat [charUtf8 operatorString, renderSubExpression operator expr] where operatorString = case operator of Not -> '!' @@ -45,9 +59,11 @@ renderUnary (operator, expr) = renderBinary :: (BinaryOperator, Expression, Expression) -> Builder renderBinary (operator, left, right) = - mconcat [renderExpression left, + mconcat [renderSubExpression operator left, + charUtf8 ' ', stringUtf8 operatorString, - renderExpression right] + charUtf8 ' ', + renderSubExpression operator right] where operatorString = case operator of Plus -> "+" @@ -133,7 +149,8 @@ renderTopLevel toplevel = case toplevel of Statement stmt -> renderStatement stmt renderProgram :: Program -> Builder -renderProgram program = renderSeparateList program ", " renderTopLevel +renderProgram program = mconcat [renderSeparateList program "\n" renderTopLevel, + charUtf8 '\n'] generateByteString :: Program -> ByteString generateByteString program = toLazyByteString $ renderProgram program @@ -142,9 +159,8 @@ generateString :: Program -> String generateString = show . generateByteString printToStdout :: Program -> IO () -printToStdout program = do +printToStdout program = Data.ByteString.Lazy.putStr $ generateByteString program - putChar '\n' printToFile :: Program -> FilePath -> IO () printToFile program filename = Data.ByteString.Lazy.writeFile filename code From 658cea4b69a56c15f9c4294c58d2121f7f91a142 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Thu, 30 Oct 2014 21:53:53 +0100 Subject: [PATCH 19/53] Implement unit test for batsh code generator --- src/Batsh.hs | 3 +++ src/Batsh/Generator.hs | 3 ++- test/UnitTest.hs | 15 +++++++++------ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Batsh.hs b/src/Batsh.hs index 15a387c..77906f0 100644 --- a/src/Batsh.hs +++ b/src/Batsh.hs @@ -21,5 +21,8 @@ parseFromAstFile path = do code <- readFile path return (read code :: Batsh.Ast.Program) +generateCode :: Batsh.Ast.Program -> String +generateCode = Batsh.Generator.generateString + generateCodeToFile :: Batsh.Ast.Program -> FilePath -> IO () generateCodeToFile = Batsh.Generator.printToFile diff --git a/src/Batsh/Generator.hs b/src/Batsh/Generator.hs index 195a45f..33b4b06 100644 --- a/src/Batsh/Generator.hs +++ b/src/Batsh/Generator.hs @@ -2,6 +2,7 @@ module Batsh.Generator where import qualified Data.ByteString import Data.ByteString.Lazy(ByteString, putStr, writeFile) +import Data.ByteString.Lazy.Char8(unpack) import Data.Monoid import Data.ByteString.Builder(Builder, charUtf8, @@ -156,7 +157,7 @@ generateByteString :: Program -> ByteString generateByteString program = toLazyByteString $ renderProgram program generateString :: Program -> String -generateString = show . generateByteString +generateString program = unpack $ generateByteString program printToStdout :: Program -> IO () printToStdout program = diff --git a/test/UnitTest.hs b/test/UnitTest.hs index f2c96dd..6e0f6a2 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -84,24 +84,27 @@ testParser = do testStatement "if (1) if (2) {true;} else {}" (If (Literal (Int 1), IfElse ( Literal (Int 2), Block [Expression (Literal (Bool True))], Block []))) +testCaseDir = "test/testcase" +testCases = ["arith"] + testParseFile :: Assertion testParseFile = do let testParseFile codeFile astFile = do expected <- parseFromAstFile astFile ast <- parseFromFile codeFile assertEqual (show ast) expected ast - let testCaseDir = "test/testcase" - let testCases = ["arith"] forM_ testCases $ \testcase -> testParseFile (testCaseDir ++ "/Batsh/" ++ testcase ++ ".batsh") (testCaseDir ++ "/BatshAst/" ++ testcase ++ ".parsed") testGenerator :: Assertion testGenerator = do - --let bs = Batsh.Generator.print $ List [Literal $ Int 3, LeftValue $ ListAccess (Identifier "a", Literal $ Int 3)] - --show bs - --assertEqual (show bs) True False - return () + forM_ testCases $ \testcase -> do + let fileName = testCaseDir ++ "/Batsh/" ++ testcase ++ ".batsh" + code <- readFile fileName + let program = parse code + let formattedCode = Batsh.generateCode program + assertEqual testcase code formattedCode main :: IO () main = defaultMainWithOpts From e96bb86b2791b77f990f580810897d37b5601e39 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Fri, 31 Oct 2014 23:26:04 +0100 Subject: [PATCH 20/53] Script for updating unit tests & more unit tests --- .gitignore | 2 +- script/update.sh | 11 +++ src/Batsh/Generator.hs | 2 +- src/Main.hs | 2 +- test/UnitTest.hs | 4 +- .../arith.parsed => Batsh/arith.ast} | 0 test/testcase/Batsh/array.ast | 95 +++++++++++++++++++ test/testcase/Batsh/array.batsh | 11 +++ test/testcase/Batsh/assignment.ast | 46 +++++++++ test/testcase/Batsh/assignment.batsh | 8 ++ 10 files changed, 176 insertions(+), 5 deletions(-) create mode 100755 script/update.sh rename test/testcase/{BatshAst/arith.parsed => Batsh/arith.ast} (100%) create mode 100644 test/testcase/Batsh/array.ast create mode 100644 test/testcase/Batsh/array.batsh create mode 100644 test/testcase/Batsh/assignment.ast create mode 100644 test/testcase/Batsh/assignment.batsh diff --git a/.gitignore b/.gitignore index 82dd65a..10110aa 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,4 @@ cabal-dev .cabal-sandbox/ cabal.sandbox.config cabal.config -batsh +/batsh diff --git a/script/update.sh b/script/update.sh new file mode 100755 index 0000000..e3e4800 --- /dev/null +++ b/script/update.sh @@ -0,0 +1,11 @@ +#!/bin/bash +inputDir=test/testcase/Batsh +for filename in ${inputDir}/*.batsh; do + caseName=$(basename -s .batsh $filename) + echo $caseName + input=${inputDir}/${caseName}.batsh + output=${inputDir}/${caseName} + ./batsh batsh $input $output --ast + diff $input $output + rm $output +done diff --git a/src/Batsh/Generator.hs b/src/Batsh/Generator.hs index 33b4b06..1c20d9d 100644 --- a/src/Batsh/Generator.hs +++ b/src/Batsh/Generator.hs @@ -118,7 +118,7 @@ renderBlock stmts level = mconcat renderStatementIndent :: Statement -> Word -> Builder renderStatementIndent stmt level = case stmt of - Comment comment -> mconcat [stringUtf8 "// ", + Comment comment -> mconcat [stringUtf8 "//", stringUtf8 comment] Block stmts -> renderBlock stmts level Expression expr -> withSemicolon $ renderExpression expr diff --git a/src/Main.hs b/src/Main.hs index 5bbd86f..df29cc4 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -96,7 +96,7 @@ batsh input target opts = do let outputWithSuffix :: String -> String -> IO (); outputWithSuffix suffix contents = do let fileName = target ++ suffix - writeFile fileName contents + writeFile fileName (contents ++ "\n") when (batshOptsTokens opts) (outputWithSuffix ".tokens" (ppShow tokens)) when (batshOptsAst opts) (outputWithSuffix ".ast" (ppShow program)) -- TODO symbols diff --git a/test/UnitTest.hs b/test/UnitTest.hs index 6e0f6a2..5e68d60 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -85,7 +85,7 @@ testParser = do Literal (Int 2), Block [Expression (Literal (Bool True))], Block []))) testCaseDir = "test/testcase" -testCases = ["arith"] +testCases = ["arith", "array", "assignment"] testParseFile :: Assertion testParseFile = do @@ -95,7 +95,7 @@ testParseFile = do assertEqual (show ast) expected ast forM_ testCases $ \testcase -> testParseFile (testCaseDir ++ "/Batsh/" ++ testcase ++ ".batsh") - (testCaseDir ++ "/BatshAst/" ++ testcase ++ ".parsed") + (testCaseDir ++ "/Batsh/" ++ testcase ++ ".ast") testGenerator :: Assertion testGenerator = do diff --git a/test/testcase/BatshAst/arith.parsed b/test/testcase/Batsh/arith.ast similarity index 100% rename from test/testcase/BatshAst/arith.parsed rename to test/testcase/Batsh/arith.ast diff --git a/test/testcase/Batsh/array.ast b/test/testcase/Batsh/array.ast new file mode 100644 index 0000000..8749c68 --- /dev/null +++ b/test/testcase/Batsh/array.ast @@ -0,0 +1,95 @@ +[ Statement + (Expression + (Assign + ( Identifier "a" + , Literal + (List + [ Literal (String "") + , Literal (String "y") + , Unary ( Negate , Literal (Int 1) ) + , Literal (Int 1) + ]) + ))) +, Statement + (Expression + (Assign + ( ListAccess ( Identifier "a" , Literal (Int 0) ) + , Binary ( Multiply , Literal (Int 2) , Literal (Int 9) ) + ))) +, Statement + (Expression + (Assign + ( ListAccess ( Identifier "a" , Literal (Int 2) ) + , Literal (String "abx") + ))) +, Statement + (Expression + (Assign + ( ListAccess ( Identifier "a" , Literal (Int 4) ) + , Binary + ( Concat + , Literal (String "5") + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) + ) + ))) +, Statement + (Expression + (Call + ( "println" + , [ LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 1) )) + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 2) )) + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 3) )) + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 4) )) + ] + ))) +, Statement + (Expression + (Assign + ( Identifier "a" + , Literal + (List [ Literal (Int 1) , Literal (Int 2) , Literal (Int 3) ]) + ))) +, Statement + (Expression + (Call + ( "println" + , [ LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 1) )) + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 2) )) + ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary + ( Multiply + , Binary + ( Concat + , Literal (String "10") + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) + ) + , Literal (Int 2) + ) + ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Call ( "len" , [ LeftValue (Identifier "a") ] ) ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary + ( Multiply + , Call ( "len" , [ LeftValue (Identifier "a") ] ) + , Literal (Int 8) + ) + ] + ))) +, Statement (Comment "println([1, 2, 3]);") +] diff --git a/test/testcase/Batsh/array.batsh b/test/testcase/Batsh/array.batsh new file mode 100644 index 0000000..3ac42a2 --- /dev/null +++ b/test/testcase/Batsh/array.batsh @@ -0,0 +1,11 @@ +a = ["", "y", -1, 1]; +a[0] = 2 * 9; +a[2] = "abx"; +a[4] = "5" ++ a[0]; +println(a[0], a[1], a[2], a[3], a[4]); +a = [1, 2, 3]; +println(a[0], a[1], a[2]); +println(("10" ++ a[0]) * 2); +println(len(a)); +println(len(a) * 8); +//println([1, 2, 3]); diff --git a/test/testcase/Batsh/assignment.ast b/test/testcase/Batsh/assignment.ast new file mode 100644 index 0000000..89c388e --- /dev/null +++ b/test/testcase/Batsh/assignment.ast @@ -0,0 +1,46 @@ +[ Statement + (Expression + (Assign + ( Identifier "a" + , Binary + ( Concat + , Literal (String "Value: ") + , Binary + ( Plus + , Literal (Int 1) + , Binary + ( Multiply + , Binary ( Plus , Literal (Int 4) , Literal (Int 6) ) + , Literal (Int 3) + ) + ) + ) + ))) +, Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "a") ] ))) +, Statement + (Expression + (Assign + ( Identifier "b" + , Binary ( Plus , Literal (Int 3) , Literal (Int 4) ) + ))) +, Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "b") ] ))) +, Statement + (Expression + (Assign ( Identifier "c" , LeftValue (Identifier "a") ))) +, Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "c") ] ))) +, Statement + (Expression + (Assign + ( Identifier "d" + , Binary + ( Concat + , LeftValue (Identifier "b") + , LeftValue (Identifier "c") + ) + ))) +, Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "d") ] ))) +] diff --git a/test/testcase/Batsh/assignment.batsh b/test/testcase/Batsh/assignment.batsh new file mode 100644 index 0000000..990e343 --- /dev/null +++ b/test/testcase/Batsh/assignment.batsh @@ -0,0 +1,8 @@ +a = "Value: " ++ 1 + (4 + 6) * 3; +println(a); +b = 3 + 4; +println(b); +c = a; +println(c); +d = b ++ c; +println(d); From 11e22e83230597f855dcbbdf554edbacf05b1a23 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Fri, 31 Oct 2014 23:58:04 +0100 Subject: [PATCH 21/53] Render indention correctly --- script/update.sh | 6 ++- src/Batsh/Generator.hs | 73 +++++++++++++++++++-------------- test/UnitTest.hs | 2 +- test/testcase/Batsh/block.ast | 19 +++++++++ test/testcase/Batsh/block.batsh | 14 +++++++ 5 files changed, 82 insertions(+), 32 deletions(-) create mode 100644 test/testcase/Batsh/block.ast create mode 100644 test/testcase/Batsh/block.batsh diff --git a/script/update.sh b/script/update.sh index e3e4800..e43ea21 100755 --- a/script/update.sh +++ b/script/update.sh @@ -7,5 +7,9 @@ for filename in ${inputDir}/*.batsh; do output=${inputDir}/${caseName} ./batsh batsh $input $output --ast diff $input $output - rm $output + if [ "$?" == $((0)) ]; then + rm $output + else + break + fi done diff --git a/src/Batsh/Generator.hs b/src/Batsh/Generator.hs index 1c20d9d..f7205d2 100644 --- a/src/Batsh/Generator.hs +++ b/src/Batsh/Generator.hs @@ -10,7 +10,6 @@ import Data.ByteString.Builder(Builder, intDec, stringUtf8, toLazyByteString) -import Data.Word import Batsh.Ast @@ -109,41 +108,55 @@ renderSeparateList list separator renderer = case list of renderExpressions :: [Expression] -> Builder renderExpressions exprs = renderSeparateList exprs ", " renderExpression -renderBlock :: [Statement] -> Word -> Builder +renderIndention :: Int -> Builder +renderIndention level = stringUtf8 (take level $ repeat ' ') + +renderBlock :: [Statement] -> Int -> Builder renderBlock stmts level = mconcat - [stringUtf8 "{", - mconcat $ map (\stmt-> renderStatementIndent stmt $ level + 2) stmts, + [stringUtf8 "{\n", + renderSeparateList stmts "\n" $ + \stmt -> renderStatementIndent stmt (level + 2), + stringUtf8 "\n", + renderIndention level, stringUtf8 "}" ] -renderStatementIndent :: Statement -> Word -> Builder -renderStatementIndent stmt level = case stmt of - Comment comment -> mconcat [stringUtf8 "//", - stringUtf8 comment] - Block stmts -> renderBlock stmts level - Expression expr -> withSemicolon $ renderExpression expr - If (expr, stmt) -> mconcat [stringUtf8 "if (", - renderExpression expr, - stringUtf8 ") ", - renderStatement stmt] - IfElse (expr, thenStmt, elseStmt) -> mconcat [stringUtf8 "if (", - renderExpression expr, - stringUtf8 ") ", - renderStatement thenStmt, - stringUtf8 " else ", - renderStatement elseStmt] - While (expr, stmt) -> mconcat [stringUtf8 "while (", - renderExpression expr, - stringUtf8 ") ", - renderStatement stmt] - Global ident -> withSemicolon $ stringUtf8 ident - Return (Just expr) -> withSemicolon $ mconcat [stringUtf8 "return ", - renderExpression expr] - Return Nothing -> withSemicolon $ stringUtf8 "return" - where withSemicolon builder = mconcat [builder, charUtf8 ';'] +renderStatementIndent :: Statement -> Int -> Builder +renderStatementIndent stmt level = + mconcat [renderIndention level, renderedStmt] + where + renderedStmt = case stmt of + Comment comment -> + mconcat [stringUtf8 "//", + stringUtf8 comment] + Block stmts -> renderBlock stmts level + Expression expr -> withSemicolon $ renderExpression expr + If (expr, stmt) -> + mconcat [stringUtf8 "if (", + renderExpression expr, + stringUtf8 ") ", + renderStatement stmt] + IfElse (expr, thenStmt, elseStmt) -> + mconcat [stringUtf8 "if (", + renderExpression expr, + stringUtf8 ") ", + renderStatement thenStmt, + stringUtf8 " else ", + renderStatement elseStmt] + While (expr, stmt) -> + mconcat [stringUtf8 "while (", + renderExpression expr, + stringUtf8 ") ", + renderStatement stmt] + Global ident -> withSemicolon $ stringUtf8 ident + Return (Just expr) -> withSemicolon $ + mconcat [stringUtf8 "return ", renderExpression expr] + Return Nothing -> withSemicolon $ stringUtf8 "return" + where + withSemicolon builder = mconcat [builder, charUtf8 ';'] renderStatement :: Statement -> Builder -renderStatement stmt = renderStatementIndent stmt (0 :: Word) +renderStatement stmt = renderStatementIndent stmt 0 renderTopLevel :: TopLevel -> Builder renderTopLevel toplevel = case toplevel of diff --git a/test/UnitTest.hs b/test/UnitTest.hs index 5e68d60..bb82d4b 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -85,7 +85,7 @@ testParser = do Literal (Int 2), Block [Expression (Literal (Bool True))], Block []))) testCaseDir = "test/testcase" -testCases = ["arith", "array", "assignment"] +testCases = ["arith", "array", "assignment", "block"] testParseFile :: Assertion testParseFile = do diff --git a/test/testcase/Batsh/block.ast b/test/testcase/Batsh/block.ast new file mode 100644 index 0000000..a36139a --- /dev/null +++ b/test/testcase/Batsh/block.ast @@ -0,0 +1,19 @@ +[ Statement (Comment "Level 0 Start") +, Statement + (Expression (Call ( "println" , [ Literal (String "Hello") ] ))) +, Statement + (Block + [ Comment "Level 1 Start" + , Expression (Call ( "println" , [ Literal (String "Lo") ] )) + , Block + [ Comment "Level 2 Start" + , Expression + (Call ( "println" , [ Literal (String "and behold") ] )) + , Comment "Level 2 End" + ] + , Comment "Level 1 End" + ]) +, Statement + (Expression (Call ( "println" , [ Literal (String "End") ] ))) +, Statement (Comment "Level 0 End") +] diff --git a/test/testcase/Batsh/block.batsh b/test/testcase/Batsh/block.batsh new file mode 100644 index 0000000..fb9eab6 --- /dev/null +++ b/test/testcase/Batsh/block.batsh @@ -0,0 +1,14 @@ +//Level 0 Start +println("Hello"); +{ + //Level 1 Start + println("Lo"); + { + //Level 2 Start + println("and behold"); + //Level 2 End + } + //Level 1 End +} +println("End"); +//Level 0 End From 3c44bcf35548dcb9b158ab0d0db2180b55304253 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Sat, 1 Nov 2014 00:02:53 +0100 Subject: [PATCH 22/53] Add operatorStr for type class Operator --- src/Batsh/Ast.hs | 77 +++++++++++++++++++++++++++--------------- src/Batsh/Generator.hs | 27 ++------------- 2 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/Batsh/Ast.hs b/src/Batsh/Ast.hs index ed3ccc5..a678cb1 100644 --- a/src/Batsh/Ast.hs +++ b/src/Batsh/Ast.hs @@ -1,8 +1,5 @@ module Batsh.Ast where -class Operator a where - precedence :: a -> Int - data Literal = Bool Bool | Int Int | Float Float @@ -24,30 +21,6 @@ data BinaryOperator = Plus | Minus | Multiply | Divide | Modulo | Concat | GreaterEqual | LessEqual | And | Or deriving (Eq,Read,Show) -instance Operator BinaryOperator where - precedence operator = case operator of - Or -> 0 - And -> 1 - Equal -> 2 - NotEqual -> 2 - ArithEqual -> 2 - ArithNotEqual -> 2 - Greater -> 3 - Less -> 3 - GreaterEqual -> 3 - LessEqual -> 3 - Concat -> 4 - Plus -> 5 - Minus -> 5 - Multiply -> 6 - Divide -> 6 - Modulo -> 6 - -instance Operator UnaryOperator where - precedence operator = case operator of - Negate -> 7 - Not -> 7 - data Expression = LeftValue LeftValue | Literal Literal | Unary (UnaryOperator, Expression) @@ -73,3 +46,53 @@ data TopLevel = Statement Statement deriving (Eq,Read,Show) type Program = [TopLevel] + +class Operator a where + precedence :: a -> Int + operatorStr :: a -> String + +instance Operator BinaryOperator where + precedence operator = case operator of + Or -> 0 + And -> 1 + Equal -> 2 + NotEqual -> 2 + ArithEqual -> 2 + ArithNotEqual -> 2 + Greater -> 3 + Less -> 3 + GreaterEqual -> 3 + LessEqual -> 3 + Concat -> 4 + Plus -> 5 + Minus -> 5 + Multiply -> 6 + Divide -> 6 + Modulo -> 6 + + operatorStr operator = case operator of + Plus -> "+" + Minus -> "-" + Multiply -> "*" + Divide -> "/" + Modulo -> "%" + Concat -> "++" + Equal -> "==" + NotEqual -> "!=" + ArithEqual -> "===" + ArithNotEqual -> "!==" + Greater -> ">" + Less -> "<" + GreaterEqual -> ">=" + LessEqual -> "<=" + And -> "&&" + Or -> "||" + +instance Operator UnaryOperator where + precedence operator = case operator of + Negate -> 7 + Not -> 7 + + operatorStr operator = case operator of + Not -> "!" + Negate -> "-" diff --git a/src/Batsh/Generator.hs b/src/Batsh/Generator.hs index f7205d2..114bbdb 100644 --- a/src/Batsh/Generator.hs +++ b/src/Batsh/Generator.hs @@ -51,37 +51,16 @@ renderSubExpression operator subExpr = renderUnary :: (UnaryOperator, Expression) -> Builder renderUnary (operator, expr) = - mconcat [charUtf8 operatorString, renderSubExpression operator expr] - where operatorString = - case operator of - Not -> '!' - Negate -> '-' + mconcat [stringUtf8 $ operatorStr operator, + renderSubExpression operator expr] renderBinary :: (BinaryOperator, Expression, Expression) -> Builder renderBinary (operator, left, right) = mconcat [renderSubExpression operator left, charUtf8 ' ', - stringUtf8 operatorString, + stringUtf8 $ operatorStr operator, charUtf8 ' ', renderSubExpression operator right] - where operatorString = - case operator of - Plus -> "+" - Minus -> "-" - Multiply -> "*" - Divide -> "/" - Modulo -> "%" - Concat -> "++" - Equal -> "==" - NotEqual -> "!=" - ArithEqual -> "===" - ArithNotEqual -> "!==" - Greater -> ">" - Less -> "<" - GreaterEqual -> ">=" - LessEqual -> "<=" - And -> "&&" - Or -> "||" renderExpression :: Expression -> Builder renderExpression expr = case expr of From 12b433f15d2b2a915d84e5a8cea2ebd55b6c02f1 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Sun, 2 Nov 2014 14:48:22 +0100 Subject: [PATCH 23/53] Fix function and indention rendering --- src/Batsh/Generator.hs | 34 +++++++---- test/UnitTest.hs | 3 +- test/testcase/Batsh/command.ast | 30 ++++++++++ test/testcase/Batsh/command.batsh | 5 ++ test/testcase/Batsh/comment.ast | 15 +++++ test/testcase/Batsh/comment.batsh | 6 ++ test/testcase/Batsh/exists.ast | 27 +++++++++ test/testcase/Batsh/exists.batsh | 11 ++++ test/testcase/Batsh/function.ast | 94 ++++++++++++++++++++++++++++++ test/testcase/Batsh/function.batsh | 36 ++++++++++++ test/testcase/Batsh/if.ast | 76 ++++++++++++++++++++++++ test/testcase/Batsh/if.batsh | 30 ++++++++++ 12 files changed, 355 insertions(+), 12 deletions(-) create mode 100644 test/testcase/Batsh/command.ast create mode 100644 test/testcase/Batsh/command.batsh create mode 100644 test/testcase/Batsh/comment.ast create mode 100644 test/testcase/Batsh/comment.batsh create mode 100644 test/testcase/Batsh/exists.ast create mode 100644 test/testcase/Batsh/exists.batsh create mode 100644 test/testcase/Batsh/function.ast create mode 100644 test/testcase/Batsh/function.batsh create mode 100644 test/testcase/Batsh/if.ast create mode 100644 test/testcase/Batsh/if.batsh diff --git a/src/Batsh/Generator.hs b/src/Batsh/Generator.hs index 114bbdb..475a5cb 100644 --- a/src/Batsh/Generator.hs +++ b/src/Batsh/Generator.hs @@ -94,15 +94,18 @@ renderBlock :: [Statement] -> Int -> Builder renderBlock stmts level = mconcat [stringUtf8 "{\n", renderSeparateList stmts "\n" $ - \stmt -> renderStatementIndent stmt (level + 2), + \stmt -> renderStatementIndent stmt (level + 2) False, stringUtf8 "\n", renderIndention level, stringUtf8 "}" ] -renderStatementIndent :: Statement -> Int -> Builder -renderStatementIndent stmt level = - mconcat [renderIndention level, renderedStmt] +renderStatementIndent :: Statement -> Int -> Bool -> Builder +renderStatementIndent stmt level isClause = + if isClause then + renderedStmt + else + mconcat [renderIndention level, renderedStmt] where renderedStmt = case stmt of Comment comment -> @@ -114,32 +117,41 @@ renderStatementIndent stmt level = mconcat [stringUtf8 "if (", renderExpression expr, stringUtf8 ") ", - renderStatement stmt] + renderClause stmt] IfElse (expr, thenStmt, elseStmt) -> mconcat [stringUtf8 "if (", renderExpression expr, stringUtf8 ") ", - renderStatement thenStmt, + renderClause thenStmt, stringUtf8 " else ", - renderStatement elseStmt] + renderClause elseStmt] While (expr, stmt) -> mconcat [stringUtf8 "while (", renderExpression expr, stringUtf8 ") ", - renderStatement stmt] - Global ident -> withSemicolon $ stringUtf8 ident + renderClause stmt] + Global ident -> withSemicolon $ + mconcat [stringUtf8 "global ", stringUtf8 ident] Return (Just expr) -> withSemicolon $ mconcat [stringUtf8 "return ", renderExpression expr] Return Nothing -> withSemicolon $ stringUtf8 "return" where - withSemicolon builder = mconcat [builder, charUtf8 ';'] + withSemicolon builder = mconcat [builder, charUtf8 ';']; + renderClause stmt = renderStatementIndent stmt level True renderStatement :: Statement -> Builder -renderStatement stmt = renderStatementIndent stmt 0 +renderStatement stmt = renderStatementIndent stmt 0 False renderTopLevel :: TopLevel -> Builder renderTopLevel toplevel = case toplevel of Statement stmt -> renderStatement stmt + Function (name, params, stmts) -> + mconcat [stringUtf8 "function ", + stringUtf8 name, + charUtf8 '(', + renderSeparateList params ", " stringUtf8, + stringUtf8 ") ", + renderBlock stmts 0] renderProgram :: Program -> Builder renderProgram program = mconcat [renderSeparateList program "\n" renderTopLevel, diff --git a/test/UnitTest.hs b/test/UnitTest.hs index bb82d4b..a02871b 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -85,7 +85,8 @@ testParser = do Literal (Int 2), Block [Expression (Literal (Bool True))], Block []))) testCaseDir = "test/testcase" -testCases = ["arith", "array", "assignment", "block"] +testCases = ["arith", "array", "assignment", "block", "command", "comment", + "exists", "function", "if"] testParseFile :: Assertion testParseFile = do diff --git a/test/testcase/Batsh/command.ast b/test/testcase/Batsh/command.ast new file mode 100644 index 0000000..d2ff049 --- /dev/null +++ b/test/testcase/Batsh/command.ast @@ -0,0 +1,30 @@ +[ Statement + (Expression + (Call + ( "call" + , [ Literal (String "println") + , Literal (String "Println Called") + ] + ))) +, Statement + (Expression + (Assign + ( Identifier "cmd" + , Binary ( Concat , Literal (String "ec") , Literal (String "ho") ) + ))) +, Statement + (Expression + (Call + ( "call" + , [ LeftValue (Identifier "cmd") , Literal (String "Echo Called") ] + ))) +, Statement + (Expression + (Assign + ( Identifier "retval" + , Call ( "echo" , [ Literal (String "Value 100%") ] ) + ))) +, Statement + (Expression + (Call ( "println" , [ LeftValue (Identifier "retval") ] ))) +] diff --git a/test/testcase/Batsh/command.batsh b/test/testcase/Batsh/command.batsh new file mode 100644 index 0000000..5198b74 --- /dev/null +++ b/test/testcase/Batsh/command.batsh @@ -0,0 +1,5 @@ +call("println", "Println Called"); +cmd = "ec" ++ "ho"; +call(cmd, "Echo Called"); +retval = echo("Value 100%"); +println(retval); diff --git a/test/testcase/Batsh/comment.ast b/test/testcase/Batsh/comment.ast new file mode 100644 index 0000000..4d2f9ba --- /dev/null +++ b/test/testcase/Batsh/comment.ast @@ -0,0 +1,15 @@ +[ Statement + (Expression (Assign ( Identifier "a" , Literal (Int 3) ))) +, Statement (Comment " This is comment 1") +, Statement + (Expression + (Assign + ( Identifier "a" + , Binary + ( Multiply , LeftValue (Identifier "a") , Literal (Int 5) ) + ))) +, Statement (Comment " This is comment 2") +, Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "a") ] ))) +, Statement (Comment "This is comment 3") +] diff --git a/test/testcase/Batsh/comment.batsh b/test/testcase/Batsh/comment.batsh new file mode 100644 index 0000000..33f5f83 --- /dev/null +++ b/test/testcase/Batsh/comment.batsh @@ -0,0 +1,6 @@ +a = 3; +// This is comment 1 +a = a * 5; +// This is comment 2 +println(a); +//This is comment 3 diff --git a/test/testcase/Batsh/exists.ast b/test/testcase/Batsh/exists.ast new file mode 100644 index 0000000..bed558d --- /dev/null +++ b/test/testcase/Batsh/exists.ast @@ -0,0 +1,27 @@ +[ Statement + (Expression + (Assign + ( Identifier "ex" + , Call ( "exists" , [ Literal (String "Makefile") ] ) + ))) +, Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "ex") ] ))) +, Statement + (Expression (Call ( "exists" , [ Literal (String "Makefile") ] ))) +, Statement + (If + ( Call ( "exists" , [ Literal (String "Makefile") ] ) + , Block + [ Expression (Call ( "println" , [ Literal (String "Yes") ] )) ] + )) +, Statement + (IfElse + ( Call ( "exists" , [ Literal (String "none") ] ) + , Block + [ Expression + (Call ( "println" , [ Literal (String "Impossible") ] )) + ] + , Block + [ Expression (Call ( "println" , [ Literal (String "No") ] )) ] + )) +] diff --git a/test/testcase/Batsh/exists.batsh b/test/testcase/Batsh/exists.batsh new file mode 100644 index 0000000..84042a9 --- /dev/null +++ b/test/testcase/Batsh/exists.batsh @@ -0,0 +1,11 @@ +ex = exists("Makefile"); +println(ex); +exists("Makefile"); +if (exists("Makefile")) { + println("Yes"); +} +if (exists("none")) { + println("Impossible"); +} else { + println("No"); +} diff --git a/test/testcase/Batsh/function.ast b/test/testcase/Batsh/function.ast new file mode 100644 index 0000000..a43c59f --- /dev/null +++ b/test/testcase/Batsh/function.ast @@ -0,0 +1,94 @@ +[ Statement (Comment " Function call") +, Function + ( "func1" + , [ "p1" , "p2" ] + , [ Expression + (Call + ( "println" + , [ LeftValue (Identifier "p1") , LeftValue (Identifier "p2") ] + )) + ] + ) +, Statement + (Expression + (Call + ( "func1" + , [ Literal (String "Hello") , Literal (String "World") ] + ))) +, Statement (Comment " Global and local variables") +, Statement + (Expression + (Assign ( Identifier "v1" , Literal (String "Global V1") ))) +, Statement + (Expression + (Assign ( Identifier "v2" , Literal (String "Global V2") ))) +, Statement + (Expression + (Assign ( Identifier "v3" , Literal (String "Global V3") ))) +, Function + ( "func2" + , [ "p" ] + , [ Expression + (Assign + ( Identifier "v1" + , Binary + ( Concat , Literal (String "Local ") , LeftValue (Identifier "p") ) + )) + , Expression (Call ( "println" , [ LeftValue (Identifier "v1") ] )) + , Expression (Call ( "println" , [ LeftValue (Identifier "v2") ] )) + , Global "v3" + , Expression + (Assign ( Identifier "v3" , Literal (String "V3 Modified.") )) + ] + ) +, Statement + (Expression (Call ( "func2" , [ Literal (String "Var") ] ))) +, Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "v1") ] ))) +, Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "v3") ] ))) +, Statement (Comment " Return value") +, Function + ( "func3" + , [ "num" ] + , [ Return + (Just + (Binary + ( Plus , LeftValue (Identifier "num") , Literal (Int 41) ))) + ] + ) +, Statement (Expression (Call ( "func3" , [ Literal (Int 4) ] ))) +, Statement (Expression (Call ( "println" , [] ))) +, Statement + (Expression + (Assign + ( Identifier "ret" , Call ( "func3" , [ Literal (Int 1) ] ) ))) +, Statement + (Expression + (Call + ( "println" + , [ Literal (String "Returned:") , LeftValue (Identifier "ret") ] + ))) +, Statement (Comment " Argument containing space") +, Function + ( "g" + , [ "text" ] + , [ Return (Just (LeftValue (Identifier "text"))) ] + ) +, Function + ( "f" + , [ "text" ] + , [ Return + (Just (Call ( "g" , [ LeftValue (Identifier "text") ] ))) + ] + ) +, Statement + (Expression + (Assign + ( Identifier "test" + , Call ( "f" , [ Literal (String "Param with space") ] ) + ))) +, Statement + (Expression + (Call ( "println" , [ LeftValue (Identifier "test") ] ))) +] diff --git a/test/testcase/Batsh/function.batsh b/test/testcase/Batsh/function.batsh new file mode 100644 index 0000000..932544f --- /dev/null +++ b/test/testcase/Batsh/function.batsh @@ -0,0 +1,36 @@ +// Function call +function func1(p1, p2) { + println(p1, p2); +} +func1("Hello", "World"); +// Global and local variables +v1 = "Global V1"; +v2 = "Global V2"; +v3 = "Global V3"; +function func2(p) { + v1 = "Local " ++ p; + println(v1); + println(v2); + global v3; + v3 = "V3 Modified."; +} +func2("Var"); +println(v1); +println(v3); +// Return value +function func3(num) { + return num + 41; +} +func3(4); +println(); +ret = func3(1); +println("Returned:", ret); +// Argument containing space +function g(text) { + return text; +} +function f(text) { + return g(text); +} +test = f("Param with space"); +println(test); diff --git a/test/testcase/Batsh/if.ast b/test/testcase/Batsh/if.ast new file mode 100644 index 0000000..c5dddab --- /dev/null +++ b/test/testcase/Batsh/if.ast @@ -0,0 +1,76 @@ +[ Statement + (If + ( Binary ( Less , Literal (Int 2) , Literal (Int 10) ) + , Block + [ Expression (Call ( "println" , [ Literal (String "Yes") ] )) ] + )) +, Statement + (IfElse + ( Literal (Bool True) + , Block + [ IfElse + ( Literal (Bool False) + , Block + [ Expression + (Assign + ( Identifier "v" + , Binary ( Plus , Literal (Int 4) , Literal (Int 1) ) + )) + ] + , Block + [ Expression (Assign ( Identifier "v" , Literal (Int 2) )) ] + ) + , If + ( Literal (Bool False) + , Expression (Call ( "println" , [ Literal (String "no") ] )) + ) + ] + , Block [] + )) +, Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "v") ] ))) +, Statement + (If + ( Binary ( Greater , Literal (Int 2) , Literal (Int 1) ) + , Expression (Call ( "println" , [ Literal (String "True") ] )) + )) +, Statement + (If + ( Binary ( ArithEqual , Literal (Int 1) , Literal (Int 12) ) + , Block + [ Expression (Call ( "println" , [ Literal (String "No") ] )) ] + )) +, Statement + (IfElse + ( Binary ( Equal , Literal (String "a") , Literal (String "b") ) + , Block + [ Expression (Call ( "println" , [ Literal (String "No") ] )) ] + , Block + [ Expression + (Call ( "println" , [ Literal (String "a is not b") ] )) + ] + )) +, Statement + (Expression (Assign ( Identifier "num" , Literal (Int 43) ))) +, Statement + (If + ( Binary + ( Equal , Literal (String "43") , LeftValue (Identifier "num") ) + , Block + [ Expression + (Call ( "println" , [ Literal (String "43 == num") ] )) + ] + )) +, Statement + (If + ( Binary + ( ArithEqual + , Literal (String "43") + , LeftValue (Identifier "num") + ) + , Block + [ Expression + (Call ( "println" , [ Literal (String "43 === num") ] )) + ] + )) +] diff --git a/test/testcase/Batsh/if.batsh b/test/testcase/Batsh/if.batsh new file mode 100644 index 0000000..cbcf37d --- /dev/null +++ b/test/testcase/Batsh/if.batsh @@ -0,0 +1,30 @@ +if (2 < 10) { + println("Yes"); +} +if (true) { + if (false) { + v = 4 + 1; + } else { + v = 2; + } + if (false) println("no"); +} else { + +} +println(v); +if (2 > 1) println("True"); +if (1 === 12) { + println("No"); +} +if ("a" == "b") { + println("No"); +} else { + println("a is not b"); +} +num = 43; +if ("43" == num) { + println("43 == num"); +} +if ("43" === num) { + println("43 === num"); +} From ecffeb7f20b91d9c63df96904ac194188a64f9de Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Sun, 2 Nov 2014 15:49:44 +0100 Subject: [PATCH 24/53] Fix library and executable dependency --- batsh.cabal | 11 +++-------- {src => executable}/Main.hs | 0 {src => library}/Batsh.hs | 0 {src => library}/Batsh/Ast.hs | 0 {src => library}/Batsh/Generator.hs | 0 {src => library}/Batsh/Lexer.x | 0 {src => library}/Batsh/Parser.y | 0 7 files changed, 3 insertions(+), 8 deletions(-) rename {src => executable}/Main.hs (100%) rename {src => library}/Batsh.hs (100%) rename {src => library}/Batsh/Ast.hs (100%) rename {src => library}/Batsh/Generator.hs (100%) rename {src => library}/Batsh/Lexer.x (100%) rename {src => library}/Batsh/Parser.y (100%) diff --git a/batsh.cabal b/batsh.cabal index 60390d8..c7abffe 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -10,23 +10,18 @@ Synopsis: A language that compiles to Bash and Windows Batch Build-Type: Simple Library + Hs-Source-Dirs: library Build-Depends: array, base, bytestring Exposed-Modules: Batsh, Batsh.Ast, Batsh.Generator, Batsh.Lexer, Batsh.Parser - Hs-Source-Dirs: src Executable batsh Main-Is: Main.hs - Hs-Source-Dirs: src - Other-Modules: Batsh, - Batsh.Ast, - Batsh.Generator, - Batsh.Lexer, - Batsh.Parser - Build-Depends: array, base, bytestring, optparse-applicative >= 0.11.0.1, pretty-show + Hs-Source-Dirs: executable + Build-Depends: array, base, Batsh, bytestring, optparse-applicative >= 0.11.0.1, pretty-show Test-Suite unit-test Type: exitcode-stdio-1.0 diff --git a/src/Main.hs b/executable/Main.hs similarity index 100% rename from src/Main.hs rename to executable/Main.hs diff --git a/src/Batsh.hs b/library/Batsh.hs similarity index 100% rename from src/Batsh.hs rename to library/Batsh.hs diff --git a/src/Batsh/Ast.hs b/library/Batsh/Ast.hs similarity index 100% rename from src/Batsh/Ast.hs rename to library/Batsh/Ast.hs diff --git a/src/Batsh/Generator.hs b/library/Batsh/Generator.hs similarity index 100% rename from src/Batsh/Generator.hs rename to library/Batsh/Generator.hs diff --git a/src/Batsh/Lexer.x b/library/Batsh/Lexer.x similarity index 100% rename from src/Batsh/Lexer.x rename to library/Batsh/Lexer.x diff --git a/src/Batsh/Parser.y b/library/Batsh/Parser.y similarity index 100% rename from src/Batsh/Parser.y rename to library/Batsh/Parser.y From 69b18b8db591cfa31ceb6377fb0180e07035f1a8 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Sun, 2 Nov 2014 15:54:04 +0100 Subject: [PATCH 25/53] Rename Lexer.True to Lexer.TTrue (TFalse) Because of Prelude.True and Prelude.False --- library/Batsh/Lexer.x | 8 ++++---- library/Batsh/Parser.y | 4 ++-- test/UnitTest.hs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/library/Batsh/Lexer.x b/library/Batsh/Lexer.x index 7c01bcc..e8ddcc4 100644 --- a/library/Batsh/Lexer.x +++ b/library/Batsh/Lexer.x @@ -47,8 +47,8 @@ tokens :- @hexadecimal{ \s -> Int (read s) } @float { \s -> Float (read s) } @string { \s -> String (tail $ init s) } - "true" { \s -> Batsh.Lexer.True } - "false" { \s -> Batsh.Lexer.False } + "true" { \s -> TTrue } + "false" { \s -> TFalse } "if" { \s -> If } "else" { \s -> Else } "while" { \s -> While } @@ -90,8 +90,8 @@ data Token = Identifier String | Int Int | Float Float | String String - | True - | False + | TTrue + | TFalse | If | Else | While diff --git a/library/Batsh/Parser.y b/library/Batsh/Parser.y index 858f222..a865f58 100644 --- a/library/Batsh/Parser.y +++ b/library/Batsh/Parser.y @@ -23,8 +23,8 @@ import qualified Batsh.Lexer as Lexer int { Lexer.Int $$ } float { Lexer.Float $$ } string { Lexer.String $$ } - true { Lexer.True } - false { Lexer.False } + true { Lexer.TTrue } + false { Lexer.TFalse } if { Lexer.If } else { Lexer.Else } while { Lexer.While } diff --git a/test/UnitTest.hs b/test/UnitTest.hs index a02871b..7fed95a 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -24,8 +24,8 @@ testLexer = do testSingle "3.14" $ Lexer.Float 3.14 testSingle "1E-8" $ Lexer.Float 1e-8 testSingle "\"string\\n\"" $ Lexer.String "string\\n" - testSingle "true" Lexer.True - testSingle "false" Lexer.False + testSingle "true" Lexer.TTrue + testSingle "false" Lexer.TFalse testSingle "if" Lexer.If testSingle "else" Lexer.Else testSingle "while" Lexer.While From fe262a396e87f5feca69d4a9931cc1ecc456af0d Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Sun, 2 Nov 2014 15:57:05 +0100 Subject: [PATCH 26/53] Explicitly specify versions of all dependencies --- batsh.cabal | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/batsh.cabal b/batsh.cabal index c7abffe..93ee60d 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -1,4 +1,4 @@ -Name: Batsh +Name: batsh Version: 0.1.0 Cabal-Version: >= 1.8 License: MIT @@ -11,7 +11,7 @@ Build-Type: Simple Library Hs-Source-Dirs: library - Build-Depends: array, base, bytestring + Build-Depends: array, base, bytestring == 0.10.4.0 Exposed-Modules: Batsh, Batsh.Ast, Batsh.Generator, @@ -21,14 +21,16 @@ Library Executable batsh Main-Is: Main.hs Hs-Source-Dirs: executable - Build-Depends: array, base, Batsh, bytestring, optparse-applicative >= 0.11.0.1, pretty-show + Build-Depends: array, base, batsh, + optparse-applicative == 0.11.0.1, + pretty-show == 1.6.8 Test-Suite unit-test Type: exitcode-stdio-1.0 Main-Is: UnitTest.hs Hs-Source-Dirs: test Build-Depends: base, - Batsh, - test-framework, - test-framework-hunit, - HUnit + batsh, + test-framework == 0.8.0.3, + test-framework-hunit == 0.3.0.1, + HUnit == 1.2.5.2 From 6c8e33a063bcdac4f270d3bd741036275b984142 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Sun, 2 Nov 2014 14:53:54 +0100 Subject: [PATCH 27/53] Add Travis-CI configuration --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..2fb1093 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: haskell +ghc: + - 7.6 + - 7.4 From 5df414d072790af7b5da0e24f01e0e5a23e977ac Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Sun, 2 Nov 2014 16:22:13 +0100 Subject: [PATCH 28/53] Add more unit test migrated all from OCaml version --- test/UnitTest.hs | 2 +- test/testcase/Batsh/recursion.ast | 104 ++++++++++++++++++++++++++++ test/testcase/Batsh/recursion.batsh | 32 +++++++++ test/testcase/Batsh/string.ast | 83 ++++++++++++++++++++++ test/testcase/Batsh/string.batsh | 13 ++++ test/testcase/Batsh/while.ast | 51 ++++++++++++++ test/testcase/Batsh/while.batsh | 17 +++++ 7 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 test/testcase/Batsh/recursion.ast create mode 100644 test/testcase/Batsh/recursion.batsh create mode 100644 test/testcase/Batsh/string.ast create mode 100644 test/testcase/Batsh/string.batsh create mode 100644 test/testcase/Batsh/while.ast create mode 100644 test/testcase/Batsh/while.batsh diff --git a/test/UnitTest.hs b/test/UnitTest.hs index 7fed95a..c7b4dbc 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -86,7 +86,7 @@ testParser = do testCaseDir = "test/testcase" testCases = ["arith", "array", "assignment", "block", "command", "comment", - "exists", "function", "if"] + "exists", "function", "if", "recursion", "string", "while"] testParseFile :: Assertion testParseFile = do diff --git a/test/testcase/Batsh/recursion.ast b/test/testcase/Batsh/recursion.ast new file mode 100644 index 0000000..cbcc058 --- /dev/null +++ b/test/testcase/Batsh/recursion.ast @@ -0,0 +1,104 @@ +[ Statement (Comment " Loop") +, Function + ( "loop" + , [ "num" ] + , [ Expression + (Call ( "println" , [ LeftValue (Identifier "num") ] )) + , If + ( Binary + ( Greater , LeftValue (Identifier "num") , Literal (Int 0) ) + , Block + [ Expression + (Call + ( "loop" + , [ Binary + ( Minus , LeftValue (Identifier "num") , Literal (Int 1) ) + ] + )) + ] + ) + ] + ) +, Statement (Expression (Call ( "loop" , [ Literal (Int 10) ] ))) +, Statement (Comment " Factorial") +, Function + ( "fact" + , [ "num" ] + , [ IfElse + ( Binary + ( ArithEqual , LeftValue (Identifier "num") , Literal (Int 0) ) + , Block [ Return (Just (Literal (Int 1))) ] + , Block + [ Return + (Just + (Binary + ( Multiply + , Call + ( "fact" + , [ Binary + ( Minus , LeftValue (Identifier "num") , Literal (Int 1) ) + ] + ) + , LeftValue (Identifier "num") + ))) + ] + ) + ] + ) +, Statement + (Expression + (Call ( "println" , [ Call ( "fact" , [ Literal (Int 5) ] ) ] ))) +, Statement (Comment " Fibonacci") +, Function + ( "fibonacci" + , [ "num" ] + , [ IfElse + ( Binary + ( ArithEqual , LeftValue (Identifier "num") , Literal (Int 0) ) + , Block [ Return (Just (Literal (Int 0))) ] + , IfElse + ( Binary + ( ArithEqual , LeftValue (Identifier "num") , Literal (Int 1) ) + , Block [ Return (Just (Literal (Int 1))) ] + , Block + [ Return + (Just + (Binary + ( Plus + , Call + ( "fibonacci" + , [ Binary + ( Minus , LeftValue (Identifier "num") , Literal (Int 2) ) + ] + ) + , Call + ( "fibonacci" + , [ Binary + ( Minus , LeftValue (Identifier "num") , Literal (Int 1) ) + ] + ) + ))) + ] + ) + ) + ] + ) +, Statement + (Expression (Assign ( Identifier "i" , Literal (Int 0) ))) +, Statement + (While + ( Binary ( Less , LeftValue (Identifier "i") , Literal (Int 7) ) + , Block + [ Expression + (Call + ( "println" + , [ Call ( "fibonacci" , [ LeftValue (Identifier "i") ] ) ] + )) + , Expression + (Assign + ( Identifier "i" + , Binary ( Plus , LeftValue (Identifier "i") , Literal (Int 1) ) + )) + ] + )) +] diff --git a/test/testcase/Batsh/recursion.batsh b/test/testcase/Batsh/recursion.batsh new file mode 100644 index 0000000..9ac6b95 --- /dev/null +++ b/test/testcase/Batsh/recursion.batsh @@ -0,0 +1,32 @@ +// Loop +function loop(num) { + println(num); + if (num > 0) { + loop(num - 1); + } +} +loop(10); +// Factorial +function fact(num) { + if (num === 0) { + return 1; + } else { + return fact(num - 1) * num; + } +} +println(fact(5)); +// Fibonacci +function fibonacci(num) { + if (num === 0) { + return 0; + } else if (num === 1) { + return 1; + } else { + return fibonacci(num - 2) + fibonacci(num - 1); + } +} +i = 0; +while (i < 7) { + println(fibonacci(i)); + i = i + 1; +} diff --git a/test/testcase/Batsh/string.ast b/test/testcase/Batsh/string.ast new file mode 100644 index 0000000..dc96d14 --- /dev/null +++ b/test/testcase/Batsh/string.ast @@ -0,0 +1,83 @@ +[ Statement + (Expression (Call ( "println" , [ Literal (String "BYVoid") ] ))) +, Statement + (Expression (Call ( "println" , [ Literal (String "Slash/") ] ))) +, Statement + (Expression + (Call ( "println" , [ Literal (String "Backslash\\\\") ] ))) +, Statement + (Expression + (Call ( "println" , [ Literal (String "Quote\\\"'") ] ))) +, Statement + (Expression + (Call ( "println" , [ Literal (String "Tab\\tTab") ] ))) +, Statement (Comment "println(\"Newline\\nLine2\");") +, Statement (Comment "println(\"!\");") +, Statement + (Expression + (Call + ( "println" + , [ Binary + ( Concat + , Binary + ( Concat + , Binary + ( Concat , Literal (String "http://") , Literal (String "www.") ) + , Literal (String "byvoid") + ) + , Literal (String ".com") + ) + ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary + ( Concat + , Binary + ( Concat + , Binary ( Divide , Literal (Int 6) , Literal (Int 2) ) + , Literal (String "BYVoid") + ) + , Binary ( Plus , Literal (Int 3) , Literal (Int 5) ) + ) + ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary ( Plus , Literal (Int 3) , Literal (String "3") ) ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary + ( Concat + , Binary ( Plus , Literal (Int 3) , Literal (String "3") ) + , Literal (String "2") + ) + ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary + ( Plus + , Literal (Int 3) + , Binary ( Concat , Literal (String "3") , Literal (String "2") ) + ) + ] + ))) +, Statement + (Expression + (Call + ( "println" + , [ Binary + ( Equal , Literal (String "BYVoid") , Literal (String "BYVoid") ) + ] + ))) +] diff --git a/test/testcase/Batsh/string.batsh b/test/testcase/Batsh/string.batsh new file mode 100644 index 0000000..d4976d9 --- /dev/null +++ b/test/testcase/Batsh/string.batsh @@ -0,0 +1,13 @@ +println("BYVoid"); +println("Slash/"); +println("Backslash\\"); +println("Quote\"'"); +println("Tab\tTab"); +//println("Newline\nLine2"); +//println("!"); +println("http://" ++ "www." ++ "byvoid" ++ ".com"); +println(6 / 2 ++ "BYVoid" ++ 3 + 5); +println(3 + "3"); +println(3 + "3" ++ "2"); +println(3 + ("3" ++ "2")); +println("BYVoid" == "BYVoid"); diff --git a/test/testcase/Batsh/while.ast b/test/testcase/Batsh/while.ast new file mode 100644 index 0000000..b7b12aa --- /dev/null +++ b/test/testcase/Batsh/while.ast @@ -0,0 +1,51 @@ +[ Statement + (Expression (Assign ( Identifier "i" , Literal (Int 0) ))) +, Statement + (While + ( Binary ( Less , LeftValue (Identifier "i") , Literal (Int 5) ) + , Block + [ Expression + (Call + ( "print" + , [ Binary + ( Concat , LeftValue (Identifier "i") , Literal (String " ") ) + ] + )) + , Expression + (Assign + ( Identifier "i" + , Binary ( Plus , LeftValue (Identifier "i") , Literal (Int 1) ) + )) + ] + )) +, Statement (Expression (Call ( "println" , [] ))) +, Statement (Comment " Fibonacci") +, Statement + (Expression (Assign ( Identifier "n" , Literal (Int 0) ))) +, Statement + (Expression (Assign ( Identifier "i" , Literal (Int 0) ))) +, Statement + (Expression (Assign ( Identifier "j" , Literal (Int 1) ))) +, Statement + (While + ( Binary ( Less , LeftValue (Identifier "n") , Literal (Int 40) ) + , Block + [ Expression + (Assign + ( Identifier "k" + , Binary + ( Plus , LeftValue (Identifier "i") , LeftValue (Identifier "j") ) + )) + , Expression + (Assign ( Identifier "i" , LeftValue (Identifier "j") )) + , Expression + (Assign ( Identifier "j" , LeftValue (Identifier "k") )) + , Expression + (Assign + ( Identifier "n" + , Binary ( Plus , LeftValue (Identifier "n") , Literal (Int 1) ) + )) + , Expression (Call ( "println" , [ LeftValue (Identifier "k") ] )) + ] + )) +] diff --git a/test/testcase/Batsh/while.batsh b/test/testcase/Batsh/while.batsh new file mode 100644 index 0000000..e14b934 --- /dev/null +++ b/test/testcase/Batsh/while.batsh @@ -0,0 +1,17 @@ +i = 0; +while (i < 5) { + print(i ++ " "); + i = i + 1; +} +println(); +// Fibonacci +n = 0; +i = 0; +j = 1; +while (n < 40) { + k = i + j; + i = j; + j = k; + n = n + 1; + println(k); +} From 8bb3eac211ec711af47c398758baddcc503cbfcb Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Sun, 2 Nov 2014 23:40:06 +0100 Subject: [PATCH 29/53] Use newtype instead of type to define Ast.Program --- library/Batsh/Ast.hs | 8 +- library/Batsh/Generator.hs | 5 +- library/Batsh/Parser.y | 2 +- test/testcase/Batsh/arith.ast | 205 ++++++++++++++-------------- test/testcase/Batsh/array.ast | 189 +++++++++++++------------- test/testcase/Batsh/assignment.ast | 93 ++++++------- test/testcase/Batsh/block.ast | 39 +++--- test/testcase/Batsh/command.ast | 61 ++++----- test/testcase/Batsh/comment.ast | 31 ++--- test/testcase/Batsh/exists.ast | 55 ++++---- test/testcase/Batsh/function.ast | 189 +++++++++++++------------- test/testcase/Batsh/if.ast | 153 ++++++++++----------- test/testcase/Batsh/recursion.ast | 209 +++++++++++++++-------------- test/testcase/Batsh/string.ast | 167 +++++++++++------------ test/testcase/Batsh/while.ast | 103 +++++++------- 15 files changed, 762 insertions(+), 747 deletions(-) diff --git a/library/Batsh/Ast.hs b/library/Batsh/Ast.hs index a678cb1..6f3c0fc 100644 --- a/library/Batsh/Ast.hs +++ b/library/Batsh/Ast.hs @@ -9,6 +9,8 @@ data Literal = Bool Bool type Identifier = String +type FunctionName = Identifier + data LeftValue = Identifier Identifier | ListAccess (LeftValue, Expression) deriving (Eq,Read,Show) @@ -26,7 +28,7 @@ data Expression = LeftValue LeftValue | Unary (UnaryOperator, Expression) | Binary (BinaryOperator, Expression, Expression) | Assign (LeftValue, Expression) - | Call (Identifier, [Parameter]) + | Call (FunctionName, [Parameter]) deriving (Eq,Read,Show) type Parameter = Expression @@ -42,10 +44,10 @@ data Statement = Comment String deriving (Eq,Read,Show) data TopLevel = Statement Statement - | Function (Identifier, [Identifier], [Statement]) + | Function (FunctionName, [Identifier], [Statement]) deriving (Eq,Read,Show) -type Program = [TopLevel] +newtype Program = Program [TopLevel] deriving (Eq,Read,Show) class Operator a where precedence :: a -> Int diff --git a/library/Batsh/Generator.hs b/library/Batsh/Generator.hs index 475a5cb..497da61 100644 --- a/library/Batsh/Generator.hs +++ b/library/Batsh/Generator.hs @@ -154,8 +154,9 @@ renderTopLevel toplevel = case toplevel of renderBlock stmts 0] renderProgram :: Program -> Builder -renderProgram program = mconcat [renderSeparateList program "\n" renderTopLevel, - charUtf8 '\n'] +renderProgram (Program program) = + mconcat [renderSeparateList program "\n" renderTopLevel, + charUtf8 '\n'] generateByteString :: Program -> ByteString generateByteString program = toLazyByteString $ renderProgram program diff --git a/library/Batsh/Parser.y b/library/Batsh/Parser.y index a865f58..6d288a2 100644 --- a/library/Batsh/Parser.y +++ b/library/Batsh/Parser.y @@ -153,7 +153,7 @@ parseError :: [Lexer.Token] -> a parseError _ = error "Parse error" parse :: String -> Ast.Program -parse = program . Lexer.scanTokens +parse code = Ast.Program $ program $ Lexer.scanTokens code parseTopLevel :: String -> Ast.TopLevel parseTopLevel = toplevel . Lexer.scanTokens diff --git a/test/testcase/Batsh/arith.ast b/test/testcase/Batsh/arith.ast index 974fda0..eb91c71 100644 --- a/test/testcase/Batsh/arith.ast +++ b/test/testcase/Batsh/arith.ast @@ -1,102 +1,103 @@ -[ Statement - (Expression (Call ( "println" , [ Literal (Bool False) ] ))) -, Statement - (Expression (Call ( "println" , [ Literal (Bool True) ] ))) -, Statement - (Expression (Call ( "println" , [ Literal (Int 42) ] ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary - ( Plus - , Literal (Int 1) - , Binary - ( Multiply - , Binary ( Plus , Literal (Int 4) , Literal (Int 6) ) - , Literal (Int 3) - ) - ) - ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary - ( Minus - , Literal (Int 8) - , Binary ( Modulo , Literal (Int 3) , Literal (Int 2) ) - ) - ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary - ( Minus , Unary ( Negate , Literal (Int 9) ) , Literal (Int 9) ) - ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary - ( Divide - , Binary ( Plus , Literal (Int 2) , Literal (Int 8) ) - , Literal (Int 3) - ) - ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary ( ArithEqual , Literal (Int 2) , Literal (Int 2) ) ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary ( ArithNotEqual , Literal (Int 6) , Literal (Int 8) ) ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary ( Greater , Literal (Int 3) , Literal (Int 2) ) ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary ( Less , Literal (Int 4) , Literal (Int 5) ) ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary ( GreaterEqual , Literal (Int 6) , Literal (Int 2) ) ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary ( LessEqual , Literal (Int 19) , Literal (Int 30) ) ] - ))) -, Statement - (Expression - (Call ( "println" , [ Unary ( Not , Literal (Bool True) ) ] ))) -, Statement - (Expression - (Call ( "println" , [ Unary ( Not , Literal (Bool False) ) ] ))) -, Statement - (Expression - (Call - ( "println" - , [ Unary - ( Not , Binary ( Minus , Literal (Int 2) , Literal (Int 1) ) ) - ] - ))) -] +Program + [ Statement + (Expression (Call ( "println" , [ Literal (Bool False) ] ))) + , Statement + (Expression (Call ( "println" , [ Literal (Bool True) ] ))) + , Statement + (Expression (Call ( "println" , [ Literal (Int 42) ] ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary + ( Plus + , Literal (Int 1) + , Binary + ( Multiply + , Binary ( Plus , Literal (Int 4) , Literal (Int 6) ) + , Literal (Int 3) + ) + ) + ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary + ( Minus + , Literal (Int 8) + , Binary ( Modulo , Literal (Int 3) , Literal (Int 2) ) + ) + ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary + ( Minus , Unary ( Negate , Literal (Int 9) ) , Literal (Int 9) ) + ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary + ( Divide + , Binary ( Plus , Literal (Int 2) , Literal (Int 8) ) + , Literal (Int 3) + ) + ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary ( ArithEqual , Literal (Int 2) , Literal (Int 2) ) ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary ( ArithNotEqual , Literal (Int 6) , Literal (Int 8) ) ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary ( Greater , Literal (Int 3) , Literal (Int 2) ) ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary ( Less , Literal (Int 4) , Literal (Int 5) ) ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary ( GreaterEqual , Literal (Int 6) , Literal (Int 2) ) ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary ( LessEqual , Literal (Int 19) , Literal (Int 30) ) ] + ))) + , Statement + (Expression + (Call ( "println" , [ Unary ( Not , Literal (Bool True) ) ] ))) + , Statement + (Expression + (Call ( "println" , [ Unary ( Not , Literal (Bool False) ) ] ))) + , Statement + (Expression + (Call + ( "println" + , [ Unary + ( Not , Binary ( Minus , Literal (Int 2) , Literal (Int 1) ) ) + ] + ))) + ] diff --git a/test/testcase/Batsh/array.ast b/test/testcase/Batsh/array.ast index 8749c68..d2ef864 100644 --- a/test/testcase/Batsh/array.ast +++ b/test/testcase/Batsh/array.ast @@ -1,95 +1,96 @@ -[ Statement - (Expression - (Assign - ( Identifier "a" - , Literal - (List - [ Literal (String "") - , Literal (String "y") - , Unary ( Negate , Literal (Int 1) ) - , Literal (Int 1) - ]) - ))) -, Statement - (Expression - (Assign - ( ListAccess ( Identifier "a" , Literal (Int 0) ) - , Binary ( Multiply , Literal (Int 2) , Literal (Int 9) ) - ))) -, Statement - (Expression - (Assign - ( ListAccess ( Identifier "a" , Literal (Int 2) ) - , Literal (String "abx") - ))) -, Statement - (Expression - (Assign - ( ListAccess ( Identifier "a" , Literal (Int 4) ) - , Binary - ( Concat - , Literal (String "5") - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) - ) - ))) -, Statement - (Expression - (Call - ( "println" - , [ LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 1) )) - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 2) )) - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 3) )) - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 4) )) - ] - ))) -, Statement - (Expression - (Assign - ( Identifier "a" - , Literal - (List [ Literal (Int 1) , Literal (Int 2) , Literal (Int 3) ]) - ))) -, Statement - (Expression - (Call - ( "println" - , [ LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 1) )) - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 2) )) - ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary - ( Multiply - , Binary - ( Concat - , Literal (String "10") - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) - ) - , Literal (Int 2) +Program + [ Statement + (Expression + (Assign + ( Identifier "a" + , Literal + (List + [ Literal (String "") + , Literal (String "y") + , Unary ( Negate , Literal (Int 1) ) + , Literal (Int 1) + ]) + ))) + , Statement + (Expression + (Assign + ( ListAccess ( Identifier "a" , Literal (Int 0) ) + , Binary ( Multiply , Literal (Int 2) , Literal (Int 9) ) + ))) + , Statement + (Expression + (Assign + ( ListAccess ( Identifier "a" , Literal (Int 2) ) + , Literal (String "abx") + ))) + , Statement + (Expression + (Assign + ( ListAccess ( Identifier "a" , Literal (Int 4) ) + , Binary + ( Concat + , Literal (String "5") + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) ) - ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Call ( "len" , [ LeftValue (Identifier "a") ] ) ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary - ( Multiply - , Call ( "len" , [ LeftValue (Identifier "a") ] ) - , Literal (Int 8) - ) - ] - ))) -, Statement (Comment "println([1, 2, 3]);") -] + ))) + , Statement + (Expression + (Call + ( "println" + , [ LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 1) )) + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 2) )) + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 3) )) + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 4) )) + ] + ))) + , Statement + (Expression + (Assign + ( Identifier "a" + , Literal + (List [ Literal (Int 1) , Literal (Int 2) , Literal (Int 3) ]) + ))) + , Statement + (Expression + (Call + ( "println" + , [ LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 1) )) + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 2) )) + ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary + ( Multiply + , Binary + ( Concat + , Literal (String "10") + , LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) + ) + , Literal (Int 2) + ) + ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Call ( "len" , [ LeftValue (Identifier "a") ] ) ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary + ( Multiply + , Call ( "len" , [ LeftValue (Identifier "a") ] ) + , Literal (Int 8) + ) + ] + ))) + , Statement (Comment "println([1, 2, 3]);") + ] diff --git a/test/testcase/Batsh/assignment.ast b/test/testcase/Batsh/assignment.ast index 89c388e..a310fc0 100644 --- a/test/testcase/Batsh/assignment.ast +++ b/test/testcase/Batsh/assignment.ast @@ -1,46 +1,47 @@ -[ Statement - (Expression - (Assign - ( Identifier "a" - , Binary - ( Concat - , Literal (String "Value: ") - , Binary - ( Plus - , Literal (Int 1) - , Binary - ( Multiply - , Binary ( Plus , Literal (Int 4) , Literal (Int 6) ) - , Literal (Int 3) - ) - ) - ) - ))) -, Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "a") ] ))) -, Statement - (Expression - (Assign - ( Identifier "b" - , Binary ( Plus , Literal (Int 3) , Literal (Int 4) ) - ))) -, Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "b") ] ))) -, Statement - (Expression - (Assign ( Identifier "c" , LeftValue (Identifier "a") ))) -, Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "c") ] ))) -, Statement - (Expression - (Assign - ( Identifier "d" - , Binary - ( Concat - , LeftValue (Identifier "b") - , LeftValue (Identifier "c") - ) - ))) -, Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "d") ] ))) -] +Program + [ Statement + (Expression + (Assign + ( Identifier "a" + , Binary + ( Concat + , Literal (String "Value: ") + , Binary + ( Plus + , Literal (Int 1) + , Binary + ( Multiply + , Binary ( Plus , Literal (Int 4) , Literal (Int 6) ) + , Literal (Int 3) + ) + ) + ) + ))) + , Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "a") ] ))) + , Statement + (Expression + (Assign + ( Identifier "b" + , Binary ( Plus , Literal (Int 3) , Literal (Int 4) ) + ))) + , Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "b") ] ))) + , Statement + (Expression + (Assign ( Identifier "c" , LeftValue (Identifier "a") ))) + , Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "c") ] ))) + , Statement + (Expression + (Assign + ( Identifier "d" + , Binary + ( Concat + , LeftValue (Identifier "b") + , LeftValue (Identifier "c") + ) + ))) + , Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "d") ] ))) + ] diff --git a/test/testcase/Batsh/block.ast b/test/testcase/Batsh/block.ast index a36139a..7ea6d30 100644 --- a/test/testcase/Batsh/block.ast +++ b/test/testcase/Batsh/block.ast @@ -1,19 +1,20 @@ -[ Statement (Comment "Level 0 Start") -, Statement - (Expression (Call ( "println" , [ Literal (String "Hello") ] ))) -, Statement - (Block - [ Comment "Level 1 Start" - , Expression (Call ( "println" , [ Literal (String "Lo") ] )) - , Block - [ Comment "Level 2 Start" - , Expression - (Call ( "println" , [ Literal (String "and behold") ] )) - , Comment "Level 2 End" - ] - , Comment "Level 1 End" - ]) -, Statement - (Expression (Call ( "println" , [ Literal (String "End") ] ))) -, Statement (Comment "Level 0 End") -] +Program + [ Statement (Comment "Level 0 Start") + , Statement + (Expression (Call ( "println" , [ Literal (String "Hello") ] ))) + , Statement + (Block + [ Comment "Level 1 Start" + , Expression (Call ( "println" , [ Literal (String "Lo") ] )) + , Block + [ Comment "Level 2 Start" + , Expression + (Call ( "println" , [ Literal (String "and behold") ] )) + , Comment "Level 2 End" + ] + , Comment "Level 1 End" + ]) + , Statement + (Expression (Call ( "println" , [ Literal (String "End") ] ))) + , Statement (Comment "Level 0 End") + ] diff --git a/test/testcase/Batsh/command.ast b/test/testcase/Batsh/command.ast index d2ff049..9c014a9 100644 --- a/test/testcase/Batsh/command.ast +++ b/test/testcase/Batsh/command.ast @@ -1,30 +1,31 @@ -[ Statement - (Expression - (Call - ( "call" - , [ Literal (String "println") - , Literal (String "Println Called") - ] - ))) -, Statement - (Expression - (Assign - ( Identifier "cmd" - , Binary ( Concat , Literal (String "ec") , Literal (String "ho") ) - ))) -, Statement - (Expression - (Call - ( "call" - , [ LeftValue (Identifier "cmd") , Literal (String "Echo Called") ] - ))) -, Statement - (Expression - (Assign - ( Identifier "retval" - , Call ( "echo" , [ Literal (String "Value 100%") ] ) - ))) -, Statement - (Expression - (Call ( "println" , [ LeftValue (Identifier "retval") ] ))) -] +Program + [ Statement + (Expression + (Call + ( "call" + , [ Literal (String "println") + , Literal (String "Println Called") + ] + ))) + , Statement + (Expression + (Assign + ( Identifier "cmd" + , Binary ( Concat , Literal (String "ec") , Literal (String "ho") ) + ))) + , Statement + (Expression + (Call + ( "call" + , [ LeftValue (Identifier "cmd") , Literal (String "Echo Called") ] + ))) + , Statement + (Expression + (Assign + ( Identifier "retval" + , Call ( "echo" , [ Literal (String "Value 100%") ] ) + ))) + , Statement + (Expression + (Call ( "println" , [ LeftValue (Identifier "retval") ] ))) + ] diff --git a/test/testcase/Batsh/comment.ast b/test/testcase/Batsh/comment.ast index 4d2f9ba..c7718f8 100644 --- a/test/testcase/Batsh/comment.ast +++ b/test/testcase/Batsh/comment.ast @@ -1,15 +1,16 @@ -[ Statement - (Expression (Assign ( Identifier "a" , Literal (Int 3) ))) -, Statement (Comment " This is comment 1") -, Statement - (Expression - (Assign - ( Identifier "a" - , Binary - ( Multiply , LeftValue (Identifier "a") , Literal (Int 5) ) - ))) -, Statement (Comment " This is comment 2") -, Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "a") ] ))) -, Statement (Comment "This is comment 3") -] +Program + [ Statement + (Expression (Assign ( Identifier "a" , Literal (Int 3) ))) + , Statement (Comment " This is comment 1") + , Statement + (Expression + (Assign + ( Identifier "a" + , Binary + ( Multiply , LeftValue (Identifier "a") , Literal (Int 5) ) + ))) + , Statement (Comment " This is comment 2") + , Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "a") ] ))) + , Statement (Comment "This is comment 3") + ] diff --git a/test/testcase/Batsh/exists.ast b/test/testcase/Batsh/exists.ast index bed558d..2d2664c 100644 --- a/test/testcase/Batsh/exists.ast +++ b/test/testcase/Batsh/exists.ast @@ -1,27 +1,28 @@ -[ Statement - (Expression - (Assign - ( Identifier "ex" - , Call ( "exists" , [ Literal (String "Makefile") ] ) - ))) -, Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "ex") ] ))) -, Statement - (Expression (Call ( "exists" , [ Literal (String "Makefile") ] ))) -, Statement - (If - ( Call ( "exists" , [ Literal (String "Makefile") ] ) - , Block - [ Expression (Call ( "println" , [ Literal (String "Yes") ] )) ] - )) -, Statement - (IfElse - ( Call ( "exists" , [ Literal (String "none") ] ) - , Block - [ Expression - (Call ( "println" , [ Literal (String "Impossible") ] )) - ] - , Block - [ Expression (Call ( "println" , [ Literal (String "No") ] )) ] - )) -] +Program + [ Statement + (Expression + (Assign + ( Identifier "ex" + , Call ( "exists" , [ Literal (String "Makefile") ] ) + ))) + , Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "ex") ] ))) + , Statement + (Expression (Call ( "exists" , [ Literal (String "Makefile") ] ))) + , Statement + (If + ( Call ( "exists" , [ Literal (String "Makefile") ] ) + , Block + [ Expression (Call ( "println" , [ Literal (String "Yes") ] )) ] + )) + , Statement + (IfElse + ( Call ( "exists" , [ Literal (String "none") ] ) + , Block + [ Expression + (Call ( "println" , [ Literal (String "Impossible") ] )) + ] + , Block + [ Expression (Call ( "println" , [ Literal (String "No") ] )) ] + )) + ] diff --git a/test/testcase/Batsh/function.ast b/test/testcase/Batsh/function.ast index a43c59f..290723c 100644 --- a/test/testcase/Batsh/function.ast +++ b/test/testcase/Batsh/function.ast @@ -1,94 +1,95 @@ -[ Statement (Comment " Function call") -, Function - ( "func1" - , [ "p1" , "p2" ] - , [ Expression - (Call - ( "println" - , [ LeftValue (Identifier "p1") , LeftValue (Identifier "p2") ] - )) - ] - ) -, Statement - (Expression - (Call - ( "func1" - , [ Literal (String "Hello") , Literal (String "World") ] - ))) -, Statement (Comment " Global and local variables") -, Statement - (Expression - (Assign ( Identifier "v1" , Literal (String "Global V1") ))) -, Statement - (Expression - (Assign ( Identifier "v2" , Literal (String "Global V2") ))) -, Statement - (Expression - (Assign ( Identifier "v3" , Literal (String "Global V3") ))) -, Function - ( "func2" - , [ "p" ] - , [ Expression - (Assign - ( Identifier "v1" - , Binary - ( Concat , Literal (String "Local ") , LeftValue (Identifier "p") ) - )) - , Expression (Call ( "println" , [ LeftValue (Identifier "v1") ] )) - , Expression (Call ( "println" , [ LeftValue (Identifier "v2") ] )) - , Global "v3" - , Expression - (Assign ( Identifier "v3" , Literal (String "V3 Modified.") )) - ] - ) -, Statement - (Expression (Call ( "func2" , [ Literal (String "Var") ] ))) -, Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "v1") ] ))) -, Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "v3") ] ))) -, Statement (Comment " Return value") -, Function - ( "func3" - , [ "num" ] - , [ Return - (Just - (Binary - ( Plus , LeftValue (Identifier "num") , Literal (Int 41) ))) - ] - ) -, Statement (Expression (Call ( "func3" , [ Literal (Int 4) ] ))) -, Statement (Expression (Call ( "println" , [] ))) -, Statement - (Expression - (Assign - ( Identifier "ret" , Call ( "func3" , [ Literal (Int 1) ] ) ))) -, Statement - (Expression - (Call - ( "println" - , [ Literal (String "Returned:") , LeftValue (Identifier "ret") ] - ))) -, Statement (Comment " Argument containing space") -, Function - ( "g" - , [ "text" ] - , [ Return (Just (LeftValue (Identifier "text"))) ] - ) -, Function - ( "f" - , [ "text" ] - , [ Return - (Just (Call ( "g" , [ LeftValue (Identifier "text") ] ))) - ] - ) -, Statement - (Expression - (Assign - ( Identifier "test" - , Call ( "f" , [ Literal (String "Param with space") ] ) - ))) -, Statement - (Expression - (Call ( "println" , [ LeftValue (Identifier "test") ] ))) -] +Program + [ Statement (Comment " Function call") + , Function + ( "func1" + , [ "p1" , "p2" ] + , [ Expression + (Call + ( "println" + , [ LeftValue (Identifier "p1") , LeftValue (Identifier "p2") ] + )) + ] + ) + , Statement + (Expression + (Call + ( "func1" + , [ Literal (String "Hello") , Literal (String "World") ] + ))) + , Statement (Comment " Global and local variables") + , Statement + (Expression + (Assign ( Identifier "v1" , Literal (String "Global V1") ))) + , Statement + (Expression + (Assign ( Identifier "v2" , Literal (String "Global V2") ))) + , Statement + (Expression + (Assign ( Identifier "v3" , Literal (String "Global V3") ))) + , Function + ( "func2" + , [ "p" ] + , [ Expression + (Assign + ( Identifier "v1" + , Binary + ( Concat , Literal (String "Local ") , LeftValue (Identifier "p") ) + )) + , Expression (Call ( "println" , [ LeftValue (Identifier "v1") ] )) + , Expression (Call ( "println" , [ LeftValue (Identifier "v2") ] )) + , Global "v3" + , Expression + (Assign ( Identifier "v3" , Literal (String "V3 Modified.") )) + ] + ) + , Statement + (Expression (Call ( "func2" , [ Literal (String "Var") ] ))) + , Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "v1") ] ))) + , Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "v3") ] ))) + , Statement (Comment " Return value") + , Function + ( "func3" + , [ "num" ] + , [ Return + (Just + (Binary + ( Plus , LeftValue (Identifier "num") , Literal (Int 41) ))) + ] + ) + , Statement (Expression (Call ( "func3" , [ Literal (Int 4) ] ))) + , Statement (Expression (Call ( "println" , [] ))) + , Statement + (Expression + (Assign + ( Identifier "ret" , Call ( "func3" , [ Literal (Int 1) ] ) ))) + , Statement + (Expression + (Call + ( "println" + , [ Literal (String "Returned:") , LeftValue (Identifier "ret") ] + ))) + , Statement (Comment " Argument containing space") + , Function + ( "g" + , [ "text" ] + , [ Return (Just (LeftValue (Identifier "text"))) ] + ) + , Function + ( "f" + , [ "text" ] + , [ Return + (Just (Call ( "g" , [ LeftValue (Identifier "text") ] ))) + ] + ) + , Statement + (Expression + (Assign + ( Identifier "test" + , Call ( "f" , [ Literal (String "Param with space") ] ) + ))) + , Statement + (Expression + (Call ( "println" , [ LeftValue (Identifier "test") ] ))) + ] diff --git a/test/testcase/Batsh/if.ast b/test/testcase/Batsh/if.ast index c5dddab..7452d32 100644 --- a/test/testcase/Batsh/if.ast +++ b/test/testcase/Batsh/if.ast @@ -1,76 +1,77 @@ -[ Statement - (If - ( Binary ( Less , Literal (Int 2) , Literal (Int 10) ) - , Block - [ Expression (Call ( "println" , [ Literal (String "Yes") ] )) ] - )) -, Statement - (IfElse - ( Literal (Bool True) - , Block - [ IfElse - ( Literal (Bool False) - , Block - [ Expression - (Assign - ( Identifier "v" - , Binary ( Plus , Literal (Int 4) , Literal (Int 1) ) - )) - ] - , Block - [ Expression (Assign ( Identifier "v" , Literal (Int 2) )) ] - ) - , If - ( Literal (Bool False) - , Expression (Call ( "println" , [ Literal (String "no") ] )) - ) - ] - , Block [] - )) -, Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "v") ] ))) -, Statement - (If - ( Binary ( Greater , Literal (Int 2) , Literal (Int 1) ) - , Expression (Call ( "println" , [ Literal (String "True") ] )) - )) -, Statement - (If - ( Binary ( ArithEqual , Literal (Int 1) , Literal (Int 12) ) - , Block - [ Expression (Call ( "println" , [ Literal (String "No") ] )) ] - )) -, Statement - (IfElse - ( Binary ( Equal , Literal (String "a") , Literal (String "b") ) - , Block - [ Expression (Call ( "println" , [ Literal (String "No") ] )) ] - , Block - [ Expression - (Call ( "println" , [ Literal (String "a is not b") ] )) - ] - )) -, Statement - (Expression (Assign ( Identifier "num" , Literal (Int 43) ))) -, Statement - (If - ( Binary - ( Equal , Literal (String "43") , LeftValue (Identifier "num") ) - , Block - [ Expression - (Call ( "println" , [ Literal (String "43 == num") ] )) - ] - )) -, Statement - (If - ( Binary - ( ArithEqual - , Literal (String "43") - , LeftValue (Identifier "num") - ) - , Block - [ Expression - (Call ( "println" , [ Literal (String "43 === num") ] )) - ] - )) -] +Program + [ Statement + (If + ( Binary ( Less , Literal (Int 2) , Literal (Int 10) ) + , Block + [ Expression (Call ( "println" , [ Literal (String "Yes") ] )) ] + )) + , Statement + (IfElse + ( Literal (Bool True) + , Block + [ IfElse + ( Literal (Bool False) + , Block + [ Expression + (Assign + ( Identifier "v" + , Binary ( Plus , Literal (Int 4) , Literal (Int 1) ) + )) + ] + , Block + [ Expression (Assign ( Identifier "v" , Literal (Int 2) )) ] + ) + , If + ( Literal (Bool False) + , Expression (Call ( "println" , [ Literal (String "no") ] )) + ) + ] + , Block [] + )) + , Statement + (Expression (Call ( "println" , [ LeftValue (Identifier "v") ] ))) + , Statement + (If + ( Binary ( Greater , Literal (Int 2) , Literal (Int 1) ) + , Expression (Call ( "println" , [ Literal (String "True") ] )) + )) + , Statement + (If + ( Binary ( ArithEqual , Literal (Int 1) , Literal (Int 12) ) + , Block + [ Expression (Call ( "println" , [ Literal (String "No") ] )) ] + )) + , Statement + (IfElse + ( Binary ( Equal , Literal (String "a") , Literal (String "b") ) + , Block + [ Expression (Call ( "println" , [ Literal (String "No") ] )) ] + , Block + [ Expression + (Call ( "println" , [ Literal (String "a is not b") ] )) + ] + )) + , Statement + (Expression (Assign ( Identifier "num" , Literal (Int 43) ))) + , Statement + (If + ( Binary + ( Equal , Literal (String "43") , LeftValue (Identifier "num") ) + , Block + [ Expression + (Call ( "println" , [ Literal (String "43 == num") ] )) + ] + )) + , Statement + (If + ( Binary + ( ArithEqual + , Literal (String "43") + , LeftValue (Identifier "num") + ) + , Block + [ Expression + (Call ( "println" , [ Literal (String "43 === num") ] )) + ] + )) + ] diff --git a/test/testcase/Batsh/recursion.ast b/test/testcase/Batsh/recursion.ast index cbcc058..80f4444 100644 --- a/test/testcase/Batsh/recursion.ast +++ b/test/testcase/Batsh/recursion.ast @@ -1,104 +1,105 @@ -[ Statement (Comment " Loop") -, Function - ( "loop" - , [ "num" ] - , [ Expression - (Call ( "println" , [ LeftValue (Identifier "num") ] )) - , If - ( Binary - ( Greater , LeftValue (Identifier "num") , Literal (Int 0) ) - , Block - [ Expression - (Call - ( "loop" - , [ Binary - ( Minus , LeftValue (Identifier "num") , Literal (Int 1) ) - ] - )) - ] - ) - ] - ) -, Statement (Expression (Call ( "loop" , [ Literal (Int 10) ] ))) -, Statement (Comment " Factorial") -, Function - ( "fact" - , [ "num" ] - , [ IfElse - ( Binary - ( ArithEqual , LeftValue (Identifier "num") , Literal (Int 0) ) - , Block [ Return (Just (Literal (Int 1))) ] - , Block - [ Return - (Just - (Binary - ( Multiply - , Call - ( "fact" - , [ Binary - ( Minus , LeftValue (Identifier "num") , Literal (Int 1) ) - ] - ) - , LeftValue (Identifier "num") - ))) - ] - ) - ] - ) -, Statement - (Expression - (Call ( "println" , [ Call ( "fact" , [ Literal (Int 5) ] ) ] ))) -, Statement (Comment " Fibonacci") -, Function - ( "fibonacci" - , [ "num" ] - , [ IfElse - ( Binary - ( ArithEqual , LeftValue (Identifier "num") , Literal (Int 0) ) - , Block [ Return (Just (Literal (Int 0))) ] - , IfElse - ( Binary - ( ArithEqual , LeftValue (Identifier "num") , Literal (Int 1) ) - , Block [ Return (Just (Literal (Int 1))) ] - , Block - [ Return - (Just - (Binary - ( Plus - , Call - ( "fibonacci" - , [ Binary - ( Minus , LeftValue (Identifier "num") , Literal (Int 2) ) - ] - ) - , Call - ( "fibonacci" - , [ Binary - ( Minus , LeftValue (Identifier "num") , Literal (Int 1) ) - ] - ) - ))) - ] - ) - ) - ] - ) -, Statement - (Expression (Assign ( Identifier "i" , Literal (Int 0) ))) -, Statement - (While - ( Binary ( Less , LeftValue (Identifier "i") , Literal (Int 7) ) - , Block - [ Expression - (Call - ( "println" - , [ Call ( "fibonacci" , [ LeftValue (Identifier "i") ] ) ] - )) - , Expression - (Assign - ( Identifier "i" - , Binary ( Plus , LeftValue (Identifier "i") , Literal (Int 1) ) - )) - ] - )) -] +Program + [ Statement (Comment " Loop") + , Function + ( "loop" + , [ "num" ] + , [ Expression + (Call ( "println" , [ LeftValue (Identifier "num") ] )) + , If + ( Binary + ( Greater , LeftValue (Identifier "num") , Literal (Int 0) ) + , Block + [ Expression + (Call + ( "loop" + , [ Binary + ( Minus , LeftValue (Identifier "num") , Literal (Int 1) ) + ] + )) + ] + ) + ] + ) + , Statement (Expression (Call ( "loop" , [ Literal (Int 10) ] ))) + , Statement (Comment " Factorial") + , Function + ( "fact" + , [ "num" ] + , [ IfElse + ( Binary + ( ArithEqual , LeftValue (Identifier "num") , Literal (Int 0) ) + , Block [ Return (Just (Literal (Int 1))) ] + , Block + [ Return + (Just + (Binary + ( Multiply + , Call + ( "fact" + , [ Binary + ( Minus , LeftValue (Identifier "num") , Literal (Int 1) ) + ] + ) + , LeftValue (Identifier "num") + ))) + ] + ) + ] + ) + , Statement + (Expression + (Call ( "println" , [ Call ( "fact" , [ Literal (Int 5) ] ) ] ))) + , Statement (Comment " Fibonacci") + , Function + ( "fibonacci" + , [ "num" ] + , [ IfElse + ( Binary + ( ArithEqual , LeftValue (Identifier "num") , Literal (Int 0) ) + , Block [ Return (Just (Literal (Int 0))) ] + , IfElse + ( Binary + ( ArithEqual , LeftValue (Identifier "num") , Literal (Int 1) ) + , Block [ Return (Just (Literal (Int 1))) ] + , Block + [ Return + (Just + (Binary + ( Plus + , Call + ( "fibonacci" + , [ Binary + ( Minus , LeftValue (Identifier "num") , Literal (Int 2) ) + ] + ) + , Call + ( "fibonacci" + , [ Binary + ( Minus , LeftValue (Identifier "num") , Literal (Int 1) ) + ] + ) + ))) + ] + ) + ) + ] + ) + , Statement + (Expression (Assign ( Identifier "i" , Literal (Int 0) ))) + , Statement + (While + ( Binary ( Less , LeftValue (Identifier "i") , Literal (Int 7) ) + , Block + [ Expression + (Call + ( "println" + , [ Call ( "fibonacci" , [ LeftValue (Identifier "i") ] ) ] + )) + , Expression + (Assign + ( Identifier "i" + , Binary ( Plus , LeftValue (Identifier "i") , Literal (Int 1) ) + )) + ] + )) + ] diff --git a/test/testcase/Batsh/string.ast b/test/testcase/Batsh/string.ast index dc96d14..60876fd 100644 --- a/test/testcase/Batsh/string.ast +++ b/test/testcase/Batsh/string.ast @@ -1,83 +1,84 @@ -[ Statement - (Expression (Call ( "println" , [ Literal (String "BYVoid") ] ))) -, Statement - (Expression (Call ( "println" , [ Literal (String "Slash/") ] ))) -, Statement - (Expression - (Call ( "println" , [ Literal (String "Backslash\\\\") ] ))) -, Statement - (Expression - (Call ( "println" , [ Literal (String "Quote\\\"'") ] ))) -, Statement - (Expression - (Call ( "println" , [ Literal (String "Tab\\tTab") ] ))) -, Statement (Comment "println(\"Newline\\nLine2\");") -, Statement (Comment "println(\"!\");") -, Statement - (Expression - (Call - ( "println" - , [ Binary - ( Concat - , Binary - ( Concat - , Binary - ( Concat , Literal (String "http://") , Literal (String "www.") ) - , Literal (String "byvoid") - ) - , Literal (String ".com") - ) - ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary - ( Concat - , Binary - ( Concat - , Binary ( Divide , Literal (Int 6) , Literal (Int 2) ) - , Literal (String "BYVoid") - ) - , Binary ( Plus , Literal (Int 3) , Literal (Int 5) ) - ) - ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary ( Plus , Literal (Int 3) , Literal (String "3") ) ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary - ( Concat - , Binary ( Plus , Literal (Int 3) , Literal (String "3") ) - , Literal (String "2") - ) - ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary - ( Plus - , Literal (Int 3) - , Binary ( Concat , Literal (String "3") , Literal (String "2") ) - ) - ] - ))) -, Statement - (Expression - (Call - ( "println" - , [ Binary - ( Equal , Literal (String "BYVoid") , Literal (String "BYVoid") ) - ] - ))) -] +Program + [ Statement + (Expression (Call ( "println" , [ Literal (String "BYVoid") ] ))) + , Statement + (Expression (Call ( "println" , [ Literal (String "Slash/") ] ))) + , Statement + (Expression + (Call ( "println" , [ Literal (String "Backslash\\\\") ] ))) + , Statement + (Expression + (Call ( "println" , [ Literal (String "Quote\\\"'") ] ))) + , Statement + (Expression + (Call ( "println" , [ Literal (String "Tab\\tTab") ] ))) + , Statement (Comment "println(\"Newline\\nLine2\");") + , Statement (Comment "println(\"!\");") + , Statement + (Expression + (Call + ( "println" + , [ Binary + ( Concat + , Binary + ( Concat + , Binary + ( Concat , Literal (String "http://") , Literal (String "www.") ) + , Literal (String "byvoid") + ) + , Literal (String ".com") + ) + ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary + ( Concat + , Binary + ( Concat + , Binary ( Divide , Literal (Int 6) , Literal (Int 2) ) + , Literal (String "BYVoid") + ) + , Binary ( Plus , Literal (Int 3) , Literal (Int 5) ) + ) + ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary ( Plus , Literal (Int 3) , Literal (String "3") ) ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary + ( Concat + , Binary ( Plus , Literal (Int 3) , Literal (String "3") ) + , Literal (String "2") + ) + ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary + ( Plus + , Literal (Int 3) + , Binary ( Concat , Literal (String "3") , Literal (String "2") ) + ) + ] + ))) + , Statement + (Expression + (Call + ( "println" + , [ Binary + ( Equal , Literal (String "BYVoid") , Literal (String "BYVoid") ) + ] + ))) + ] diff --git a/test/testcase/Batsh/while.ast b/test/testcase/Batsh/while.ast index b7b12aa..86791f0 100644 --- a/test/testcase/Batsh/while.ast +++ b/test/testcase/Batsh/while.ast @@ -1,51 +1,52 @@ -[ Statement - (Expression (Assign ( Identifier "i" , Literal (Int 0) ))) -, Statement - (While - ( Binary ( Less , LeftValue (Identifier "i") , Literal (Int 5) ) - , Block - [ Expression - (Call - ( "print" - , [ Binary - ( Concat , LeftValue (Identifier "i") , Literal (String " ") ) - ] - )) - , Expression - (Assign - ( Identifier "i" - , Binary ( Plus , LeftValue (Identifier "i") , Literal (Int 1) ) - )) - ] - )) -, Statement (Expression (Call ( "println" , [] ))) -, Statement (Comment " Fibonacci") -, Statement - (Expression (Assign ( Identifier "n" , Literal (Int 0) ))) -, Statement - (Expression (Assign ( Identifier "i" , Literal (Int 0) ))) -, Statement - (Expression (Assign ( Identifier "j" , Literal (Int 1) ))) -, Statement - (While - ( Binary ( Less , LeftValue (Identifier "n") , Literal (Int 40) ) - , Block - [ Expression - (Assign - ( Identifier "k" - , Binary - ( Plus , LeftValue (Identifier "i") , LeftValue (Identifier "j") ) - )) - , Expression - (Assign ( Identifier "i" , LeftValue (Identifier "j") )) - , Expression - (Assign ( Identifier "j" , LeftValue (Identifier "k") )) - , Expression - (Assign - ( Identifier "n" - , Binary ( Plus , LeftValue (Identifier "n") , Literal (Int 1) ) - )) - , Expression (Call ( "println" , [ LeftValue (Identifier "k") ] )) - ] - )) -] +Program + [ Statement + (Expression (Assign ( Identifier "i" , Literal (Int 0) ))) + , Statement + (While + ( Binary ( Less , LeftValue (Identifier "i") , Literal (Int 5) ) + , Block + [ Expression + (Call + ( "print" + , [ Binary + ( Concat , LeftValue (Identifier "i") , Literal (String " ") ) + ] + )) + , Expression + (Assign + ( Identifier "i" + , Binary ( Plus , LeftValue (Identifier "i") , Literal (Int 1) ) + )) + ] + )) + , Statement (Expression (Call ( "println" , [] ))) + , Statement (Comment " Fibonacci") + , Statement + (Expression (Assign ( Identifier "n" , Literal (Int 0) ))) + , Statement + (Expression (Assign ( Identifier "i" , Literal (Int 0) ))) + , Statement + (Expression (Assign ( Identifier "j" , Literal (Int 1) ))) + , Statement + (While + ( Binary ( Less , LeftValue (Identifier "n") , Literal (Int 40) ) + , Block + [ Expression + (Assign + ( Identifier "k" + , Binary + ( Plus , LeftValue (Identifier "i") , LeftValue (Identifier "j") ) + )) + , Expression + (Assign ( Identifier "i" , LeftValue (Identifier "j") )) + , Expression + (Assign ( Identifier "j" , LeftValue (Identifier "k") )) + , Expression + (Assign + ( Identifier "n" + , Binary ( Plus , LeftValue (Identifier "n") , Literal (Int 1) ) + )) + , Expression (Call ( "println" , [ LeftValue (Identifier "k") ] )) + ] + )) + ] From 6679c3b170c630f0cfb4afec655ceba209a8666b Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Mon, 3 Nov 2014 00:56:20 +0100 Subject: [PATCH 30/53] Symbol table Implement skeleton of symbol table --- batsh.cabal | 6 ++-- library/Batsh.hs | 4 +++ library/Batsh/SymbolTable.hs | 59 ++++++++++++++++++++++++++++++++++++ test/UnitTest.hs | 12 +++++++- 4 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 library/Batsh/SymbolTable.hs diff --git a/batsh.cabal b/batsh.cabal index 93ee60d..b67f43c 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -11,17 +11,18 @@ Build-Type: Simple Library Hs-Source-Dirs: library - Build-Depends: array, base, bytestring == 0.10.4.0 + Build-Depends: array, base, bytestring == 0.10.4.0, containers >= 0.5 Exposed-Modules: Batsh, Batsh.Ast, Batsh.Generator, Batsh.Lexer, Batsh.Parser + Batsh.SymbolTable Executable batsh Main-Is: Main.hs Hs-Source-Dirs: executable - Build-Depends: array, base, batsh, + Build-Depends: base, batsh, optparse-applicative == 0.11.0.1, pretty-show == 1.6.8 @@ -31,6 +32,7 @@ Test-Suite unit-test Hs-Source-Dirs: test Build-Depends: base, batsh, + containers >= 0.5, test-framework == 0.8.0.3, test-framework-hunit == 0.3.0.1, HUnit == 1.2.5.2 diff --git a/library/Batsh.hs b/library/Batsh.hs index 77906f0..068e371 100644 --- a/library/Batsh.hs +++ b/library/Batsh.hs @@ -4,6 +4,7 @@ import qualified Batsh.Ast import qualified Batsh.Generator import qualified Batsh.Lexer import qualified Batsh.Parser +import qualified Batsh.SymbolTable as SymbolTable lex :: String -> [Batsh.Lexer.Token] lex code = Batsh.Lexer.scanTokens code @@ -26,3 +27,6 @@ generateCode = Batsh.Generator.generateString generateCodeToFile :: Batsh.Ast.Program -> FilePath -> IO () generateCodeToFile = Batsh.Generator.printToFile + +createSymbolTable :: Batsh.Ast.Program -> SymbolTable.SymbolTable +createSymbolTable = SymbolTable.create diff --git a/library/Batsh/SymbolTable.hs b/library/Batsh/SymbolTable.hs new file mode 100644 index 0000000..fe90a0b --- /dev/null +++ b/library/Batsh/SymbolTable.hs @@ -0,0 +1,59 @@ +module Batsh.SymbolTable where + +import qualified Data.Map.Strict as SMap + +import Batsh.Ast + +newtype SymbolTable = SymbolTable Table + deriving (Eq, Read, Show) + +type Table = SMap.Map Identifier Symbol + +type Symbol = (Identifier, Scope) + +data Scope = SGlobal | SFunction FunctionName + deriving (Eq, Read, Show) + +create :: Program -> SymbolTable +create (Program program) = + SymbolTable $ SMap.unions $ map processToplevel program + +processToplevel :: TopLevel -> Table +processToplevel topLevel = case topLevel of + Statement stmt -> processStatement SMap.empty SGlobal stmt + Function func -> SMap.empty + +processStatement :: Table -> Scope -> Statement -> Table +processStatement table scope stmt = case stmt of + Block stmts -> processStatements table scope stmts + Expression expr -> processExpression table scope expr + If (expr, stmt) -> table -- FIXME + IfElse (expr, thenStmt, elseStmt) -> table -- FIXME + While (expr, stmt) -> table -- FIXME + Global ident -> processIdentifier table SGlobal ident + Return (Just expr) -> table -- FIXME + _ -> table + +processStatements :: Table -> Scope -> [Statement] -> Table +processStatements table scope stmts = + foldl (\table stmt -> processStatement table scope stmt) table stmts + +processExpression :: Table -> Scope -> Expression -> Table +processExpression table scope expr = case expr of + Assign (lvalue, subExpr) -> processLeftValue table scope lvalue + -- FIXME + +processLeftValue :: Table -> Scope -> LeftValue -> Table +processLeftValue table scope lvalue = case lvalue of + Identifier ident -> processIdentifier table scope ident + ListAccess (lvalue, subExpr) -> table -- FIXME + +processIdentifier :: Table -> Scope -> Identifier -> Table +processIdentifier table scope ident = + SMap.alter update ident table + where + update original = case original of + Nothing -> newSymbol + Just (_, SFunction _) -> newSymbol + Just (_, SGlobal) -> original + where newSymbol = Just (ident, scope) diff --git a/test/UnitTest.hs b/test/UnitTest.hs index c7b4dbc..b608363 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -3,9 +3,11 @@ import Data.Monoid import Test.HUnit import Test.Framework import Test.Framework.Providers.HUnit +import qualified Data.Map.Strict as SMap import Batsh import Batsh.Ast +import Batsh.SymbolTable import qualified Batsh.Generator import qualified Batsh.Lexer as Lexer import qualified Batsh.Parser @@ -107,10 +109,18 @@ testGenerator = do let formattedCode = Batsh.generateCode program assertEqual testcase code formattedCode +testSymbolTable :: Assertion +testSymbolTable = do + let ast = Batsh.parse "a = 1;" + let symbolTable = Batsh.createSymbolTable ast + let expected = SymbolTable (SMap.fromList [("a",("a",SGlobal))]) + assertEqual (show symbolTable) expected symbolTable + main :: IO () main = defaultMainWithOpts [testCase "Lexer" testLexer, testCase "Parser" testParser, testCase "ParseFile" testParseFile, - testCase "Generator" testGenerator] + testCase "Generator" testGenerator, + testCase "SymbolTable" testSymbolTable] mempty From 475a15bb69ebd1d31121ec75e3721a1ec1c24b05 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Mon, 3 Nov 2014 01:13:32 +0100 Subject: [PATCH 31/53] Break UnitTest.hs into files --- test/GeneratorTest.hs | 19 ++++++ test/LexerTest.hs | 53 +++++++++++++++++ test/ParserTest.hs | 46 +++++++++++++++ test/SymbolTableTest.hs | 14 +++++ test/UnitTest.hs | 127 +++------------------------------------- 5 files changed, 141 insertions(+), 118 deletions(-) create mode 100644 test/GeneratorTest.hs create mode 100644 test/LexerTest.hs create mode 100644 test/ParserTest.hs create mode 100644 test/SymbolTableTest.hs diff --git a/test/GeneratorTest.hs b/test/GeneratorTest.hs new file mode 100644 index 0000000..1505ea1 --- /dev/null +++ b/test/GeneratorTest.hs @@ -0,0 +1,19 @@ +module GeneratorTest where + +import qualified Batsh +import Batsh.Generator +import Control.Monad +import Test.HUnit + +testCaseDir = "test/testcase" +testCases = ["arith", "array", "assignment", "block", "command", "comment", + "exists", "function", "if", "recursion", "string", "while"] + +testGenerator :: Assertion +testGenerator = do + forM_ testCases $ \testcase -> do + let fileName = testCaseDir ++ "/Batsh/" ++ testcase ++ ".batsh" + code <- readFile fileName + let program = Batsh.parse code + let formattedCode = generateString program + assertEqual testcase code formattedCode diff --git a/test/LexerTest.hs b/test/LexerTest.hs new file mode 100644 index 0000000..6eae820 --- /dev/null +++ b/test/LexerTest.hs @@ -0,0 +1,53 @@ +module LexerTest where + +import Batsh.Lexer +import Test.HUnit + +testLexer :: Assertion +testLexer = do + let testSingle str expected = do + let tokens = scanTokens str + let token = head tokens + assertEqual "Number of tokens" 1 (length tokens) + assertEqual (show token) expected token + testSingle "variable" $ Identifier "variable" + testSingle "//a line comment" $ Comment "a line comment" + testSingle "42" $ Int 42 + testSingle "0xFF" $ Int 255 + testSingle "3.14" $ Float 3.14 + testSingle "1E-8" $ Float 1e-8 + testSingle "\"string\\n\"" $ String "string\\n" + testSingle "true" TTrue + testSingle "false" TFalse + testSingle "if" If + testSingle "else" Else + testSingle "while" While + testSingle "function" Function + testSingle "global" Global + testSingle "return" Return + testSingle "!" Not + testSingle ";" Semicolon + testSingle "," Comma + testSingle "+" Plus + testSingle "-" Minus + testSingle "*" Multiply + testSingle "/" Divide + testSingle "%" Modulo + testSingle "++" Concat + testSingle "=" Assign + testSingle "==" Equal + testSingle "!=" NotEqual + testSingle "===" ArithEqual + testSingle "!==" ArithNotEqual + testSingle ">" Greater + testSingle "<" Less + testSingle ">=" GreaterEqual + testSingle "<=" LessEqual + testSingle "&&" And + testSingle "||" Or + testSingle "(" LParen + testSingle ")" RParen + testSingle "[" LBrack + testSingle "]" RBrack + testSingle "{" LBrace + testSingle "}" RBrace diff --git a/test/ParserTest.hs b/test/ParserTest.hs new file mode 100644 index 0000000..24dca24 --- /dev/null +++ b/test/ParserTest.hs @@ -0,0 +1,46 @@ +module ParserTest where + +import qualified Batsh +import Batsh.Ast +import Batsh.Parser +import Control.Monad +import Test.HUnit + +testParser :: Assertion +testParser = do + let testAst :: (Show a, Eq a) => (String -> a) -> String -> a -> Assertion; + testAst parser code expected = + assertEqual (show ast) expected ast + where ast = parser code + let testProgram = testAst parse + let testTopLevel = testAst parseTopLevel + let testStatement = testAst parseStatement + let testExpression = testAst parseExpression + -- Expression + testExpression "3" (Literal $ Int 3) + testExpression "[4.2 + 3, \"str\", []]" (Literal $ List [Binary (Plus, + Literal $ Float 4.2 , Literal $ Int 3), Literal $ String "str", + Literal $ List []]) + testExpression "a+2+9*4e2 > 5 || true && 4 != \"str\"" (Binary (Or, Binary ( + Greater, Binary (Plus, Binary (Plus, LeftValue (Identifier "a"), Literal ( + Int 2)), Binary (Multiply, Literal (Int 9), Literal (Float 400.0))), Literal + (Int 5)), Binary (And, Literal (Bool True), Binary (NotEqual, Literal (Int + 4), Literal (String "str"))))) + -- Statement + testStatement "func(4);" (Expression $ Call ("func", [Literal $ Int 4])) + testStatement "if (1) if (2) {true;} else {}" (If (Literal (Int 1), IfElse ( + Literal (Int 2), Block [Expression (Literal (Bool True))], Block []))) + +testCaseDir = "test/testcase" +testCases = ["arith", "array", "assignment", "block", "command", "comment", + "exists", "function", "if", "recursion", "string", "while"] + +testParseFile :: Assertion +testParseFile = do + let testParseFile codeFile astFile = do + expected <- Batsh.parseFromAstFile astFile + ast <- Batsh.parseFromFile codeFile + assertEqual (show ast) expected ast + forM_ testCases $ \testcase -> + testParseFile (testCaseDir ++ "/Batsh/" ++ testcase ++ ".batsh") + (testCaseDir ++ "/Batsh/" ++ testcase ++ ".ast") diff --git a/test/SymbolTableTest.hs b/test/SymbolTableTest.hs new file mode 100644 index 0000000..edb06a5 --- /dev/null +++ b/test/SymbolTableTest.hs @@ -0,0 +1,14 @@ +module SymbolTableTest where + +import qualified Batsh +import Batsh.Ast +import Batsh.SymbolTable +import qualified Data.Map.Strict as SMap +import Test.HUnit + +testSymbolTable :: Assertion +testSymbolTable = do + let ast = Batsh.parse "a = 1;" + let symbolTable = Batsh.createSymbolTable ast + let expected = SymbolTable (SMap.fromList [("a",("a",SGlobal))]) + assertEqual (show symbolTable) expected symbolTable diff --git a/test/UnitTest.hs b/test/UnitTest.hs index b608363..18cd27a 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -1,126 +1,17 @@ -import Control.Monad import Data.Monoid -import Test.HUnit import Test.Framework import Test.Framework.Providers.HUnit -import qualified Data.Map.Strict as SMap -import Batsh -import Batsh.Ast -import Batsh.SymbolTable -import qualified Batsh.Generator -import qualified Batsh.Lexer as Lexer -import qualified Batsh.Parser - -testLexer :: Assertion -testLexer = do - let testSingle str expected = do - let tokens = Lexer.scanTokens str - let token = head tokens - assertEqual "Number of tokens" 1 (length tokens) - assertEqual (show token) expected token - testSingle "variable" $ Lexer.Identifier "variable" - testSingle "//a line comment" $ Lexer.Comment "a line comment" - testSingle "42" $ Lexer.Int 42 - testSingle "0xFF" $ Lexer.Int 255 - testSingle "3.14" $ Lexer.Float 3.14 - testSingle "1E-8" $ Lexer.Float 1e-8 - testSingle "\"string\\n\"" $ Lexer.String "string\\n" - testSingle "true" Lexer.TTrue - testSingle "false" Lexer.TFalse - testSingle "if" Lexer.If - testSingle "else" Lexer.Else - testSingle "while" Lexer.While - testSingle "function" Lexer.Function - testSingle "global" Lexer.Global - testSingle "return" Lexer.Return - testSingle "!" Lexer.Not - testSingle ";" Lexer.Semicolon - testSingle "," Lexer.Comma - testSingle "+" Lexer.Plus - testSingle "-" Lexer.Minus - testSingle "*" Lexer.Multiply - testSingle "/" Lexer.Divide - testSingle "%" Lexer.Modulo - testSingle "++" Lexer.Concat - testSingle "=" Lexer.Assign - testSingle "==" Lexer.Equal - testSingle "!=" Lexer.NotEqual - testSingle "===" Lexer.ArithEqual - testSingle "!==" Lexer.ArithNotEqual - testSingle ">" Lexer.Greater - testSingle "<" Lexer.Less - testSingle ">=" Lexer.GreaterEqual - testSingle "<=" Lexer.LessEqual - testSingle "&&" Lexer.And - testSingle "||" Lexer.Or - testSingle "(" Lexer.LParen - testSingle ")" Lexer.RParen - testSingle "[" Lexer.LBrack - testSingle "]" Lexer.RBrack - testSingle "{" Lexer.LBrace - testSingle "}" Lexer.RBrace - -testParser :: Assertion -testParser = do - let testAst :: (Show a, Eq a) => (String -> a) -> String -> a -> Assertion; - testAst parser code expected = - assertEqual (show ast) expected ast - where ast = parser code - let testProgram = testAst Batsh.Parser.parse - let testTopLevel = testAst Batsh.Parser.parseTopLevel - let testStatement = testAst Batsh.Parser.parseStatement - let testExpression = testAst Batsh.Parser.parseExpression - -- Expression - testExpression "3" (Literal $ Int 3) - testExpression "[4.2 + 3, \"str\", []]" (Literal $ List [Binary (Plus, - Literal $ Float 4.2 , Literal $ Int 3), Literal $ String "str", - Literal $ List []]) - testExpression "a+2+9*4e2 > 5 || true && 4 != \"str\"" (Binary (Or, Binary ( - Greater, Binary (Plus, Binary (Plus, LeftValue (Identifier "a"), Literal ( - Int 2)), Binary (Multiply, Literal (Int 9), Literal (Float 400.0))), Literal - (Int 5)), Binary (And, Literal (Bool True), Binary (NotEqual, Literal (Int - 4), Literal (String "str"))))) - -- Statement - testStatement "func(4);" (Expression $ Call ("func", [Literal $ Int 4])) - testStatement "if (1) if (2) {true;} else {}" (If (Literal (Int 1), IfElse ( - Literal (Int 2), Block [Expression (Literal (Bool True))], Block []))) - -testCaseDir = "test/testcase" -testCases = ["arith", "array", "assignment", "block", "command", "comment", - "exists", "function", "if", "recursion", "string", "while"] - -testParseFile :: Assertion -testParseFile = do - let testParseFile codeFile astFile = do - expected <- parseFromAstFile astFile - ast <- parseFromFile codeFile - assertEqual (show ast) expected ast - forM_ testCases $ \testcase -> - testParseFile (testCaseDir ++ "/Batsh/" ++ testcase ++ ".batsh") - (testCaseDir ++ "/Batsh/" ++ testcase ++ ".ast") - -testGenerator :: Assertion -testGenerator = do - forM_ testCases $ \testcase -> do - let fileName = testCaseDir ++ "/Batsh/" ++ testcase ++ ".batsh" - code <- readFile fileName - let program = parse code - let formattedCode = Batsh.generateCode program - assertEqual testcase code formattedCode - -testSymbolTable :: Assertion -testSymbolTable = do - let ast = Batsh.parse "a = 1;" - let symbolTable = Batsh.createSymbolTable ast - let expected = SymbolTable (SMap.fromList [("a",("a",SGlobal))]) - assertEqual (show symbolTable) expected symbolTable +import qualified GeneratorTest +import qualified LexerTest +import qualified ParserTest +import qualified SymbolTableTest main :: IO () main = defaultMainWithOpts - [testCase "Lexer" testLexer, - testCase "Parser" testParser, - testCase "ParseFile" testParseFile, - testCase "Generator" testGenerator, - testCase "SymbolTable" testSymbolTable] + [testCase "Lexer" LexerTest.testLexer, + testCase "Parser" ParserTest.testParser, + testCase "ParseFile" ParserTest.testParseFile, + testCase "Generator" GeneratorTest.testGenerator, + testCase "SymbolTable" SymbolTableTest.testSymbolTable] mempty From abb861f60495649543b01f771a426b8d6706781d Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Mon, 3 Nov 2014 20:09:04 +0100 Subject: [PATCH 32/53] Output symbol table if --symbols is set --- executable/Main.hs | 4 ++-- script/update.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/executable/Main.hs b/executable/Main.hs index df29cc4..b5985d5 100644 --- a/executable/Main.hs +++ b/executable/Main.hs @@ -93,15 +93,15 @@ batsh input target opts = do code <- readFile input let program = Batsh.parse code let tokens = Batsh.lex code + let symbols = Batsh.createSymbolTable program let outputWithSuffix :: String -> String -> IO (); outputWithSuffix suffix contents = do let fileName = target ++ suffix writeFile fileName (contents ++ "\n") when (batshOptsTokens opts) (outputWithSuffix ".tokens" (ppShow tokens)) when (batshOptsAst opts) (outputWithSuffix ".ast" (ppShow program)) - -- TODO symbols + when (batshOptsSymbols opts) (outputWithSuffix ".symbols" (ppShow symbols)) Batsh.generateCodeToFile program target - return () pinfo :: ParserInfo Args pinfo = info parser $ diff --git a/script/update.sh b/script/update.sh index e43ea21..93643cf 100755 --- a/script/update.sh +++ b/script/update.sh @@ -5,7 +5,7 @@ for filename in ${inputDir}/*.batsh; do echo $caseName input=${inputDir}/${caseName}.batsh output=${inputDir}/${caseName} - ./batsh batsh $input $output --ast + ./batsh batsh $input $output --ast --symbols diff $input $output if [ "$?" == $((0)) ]; then rm $output From b00821067f60e500adb2220f6ccd296925441c57 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Mon, 3 Nov 2014 20:45:49 +0100 Subject: [PATCH 33/53] Symbol table with hierarchy --- library/Batsh/Ast.hs | 8 +- library/Batsh/SymbolTable.hs | 147 +++++++++++++++++++++---- test/SymbolTableTest.hs | 2 +- test/testcase/Batsh/arith.symbols | 2 + test/testcase/Batsh/array.symbols | 7 ++ test/testcase/Batsh/assignment.symbols | 14 +++ test/testcase/Batsh/block.symbols | 2 + test/testcase/Batsh/command.symbols | 12 ++ test/testcase/Batsh/comment.symbols | 7 ++ test/testcase/Batsh/exists.symbols | 9 ++ test/testcase/Batsh/function.ast | 1 + test/testcase/Batsh/function.batsh | 1 + test/testcase/Batsh/function.symbols | 62 +++++++++++ test/testcase/Batsh/if.symbols | 12 ++ test/testcase/Batsh/recursion.symbols | 35 ++++++ test/testcase/Batsh/string.symbols | 2 + test/testcase/Batsh/while.symbols | 14 +++ 17 files changed, 309 insertions(+), 28 deletions(-) create mode 100644 test/testcase/Batsh/arith.symbols create mode 100644 test/testcase/Batsh/array.symbols create mode 100644 test/testcase/Batsh/assignment.symbols create mode 100644 test/testcase/Batsh/block.symbols create mode 100644 test/testcase/Batsh/command.symbols create mode 100644 test/testcase/Batsh/comment.symbols create mode 100644 test/testcase/Batsh/exists.symbols create mode 100644 test/testcase/Batsh/function.symbols create mode 100644 test/testcase/Batsh/if.symbols create mode 100644 test/testcase/Batsh/recursion.symbols create mode 100644 test/testcase/Batsh/string.symbols create mode 100644 test/testcase/Batsh/while.symbols diff --git a/library/Batsh/Ast.hs b/library/Batsh/Ast.hs index 6f3c0fc..4425ab7 100644 --- a/library/Batsh/Ast.hs +++ b/library/Batsh/Ast.hs @@ -28,11 +28,9 @@ data Expression = LeftValue LeftValue | Unary (UnaryOperator, Expression) | Binary (BinaryOperator, Expression, Expression) | Assign (LeftValue, Expression) - | Call (FunctionName, [Parameter]) + | Call (FunctionName, [Expression]) deriving (Eq,Read,Show) -type Parameter = Expression - data Statement = Comment String | Block [Statement] | Expression Expression @@ -44,9 +42,11 @@ data Statement = Comment String deriving (Eq,Read,Show) data TopLevel = Statement Statement - | Function (FunctionName, [Identifier], [Statement]) + | Function (FunctionName, [Parameter], [Statement]) deriving (Eq,Read,Show) +type Parameter = Identifier + newtype Program = Program [TopLevel] deriving (Eq,Read,Show) class Operator a where diff --git a/library/Batsh/SymbolTable.hs b/library/Batsh/SymbolTable.hs index fe90a0b..c7312ed 100644 --- a/library/Batsh/SymbolTable.hs +++ b/library/Batsh/SymbolTable.hs @@ -1,37 +1,126 @@ -module Batsh.SymbolTable where +module Batsh.SymbolTable(create, + lookup, + SymbolTable) where +import Batsh.Ast +import qualified Data.List as List import qualified Data.Map.Strict as SMap +import Prelude hiding(lookup) -import Batsh.Ast +newtype SymbolTable = SymbolTable MapScopeTable + deriving (Eq, Read, Show) -newtype SymbolTable = SymbolTable Table +-- (key: Scope, value: Table) +type MapScopeTable = SMap.Map Scope Table + +-- table: (key: Identifier, value: Symbol), parentScope +newtype Table = Table (MapIdentifierSymbol, Maybe Scope) deriving (Eq, Read, Show) -type Table = SMap.Map Identifier Symbol +type MapIdentifierSymbol = SMap.Map Identifier Symbol -type Symbol = (Identifier, Scope) +type Symbol = (Identifier, SymbolType, Scope) -data Scope = SGlobal | SFunction FunctionName +data SymbolType = STVariable | STParameter | STFunction deriving (Eq, Read, Show) +data Scope = SGlobal | SFunction FunctionName | SUnnamedBlock BlockID + deriving (Eq, Read, Show, Ord) + +type BlockID = String + +lookupScope :: SymbolTable -> Scope -> Maybe Table +lookupScope (SymbolTable symbolTable) scope = SMap.lookup scope symbolTable + +lookup :: SymbolTable -> Scope -> Identifier -> Maybe Symbol +lookup symbolTable scope ident = + case lookupScope symbolTable scope of + Just (Table (table, parentScope)) -> + case SMap.lookup ident table of + Just symbol -> Just symbol -- Symbol found + Nothing -> -- Recursively lookup parent scopes + case parentScope of + Just scope -> Batsh.SymbolTable.lookup symbolTable scope ident + Nothing -> Nothing -- Already the top scope (SGlobal) + Nothing -> Nothing -- scope does not exist + create :: Program -> SymbolTable create (Program program) = - SymbolTable $ SMap.unions $ map processToplevel program + SymbolTable $ SMap.fromList $ (SGlobal, globalTable) : functionTables + where + (functions, topLevelStmts) = List.partition (\topl -> case topl of + Function _ -> True + Statement _ -> False + ) program; + stmts = map (\(Statement stmt) -> stmt) topLevelStmts + -- Add function definitions to global table + functionDefTable = Table (foldl addFuncDef SMap.empty functions, Nothing) + -- Add global statements to global table + globalTable0 = processStatements functionDefTable SGlobal stmts + globalTable = addSymbols globalTable0 globalSymbols + -- Create symbol tables for every function + functionTables :: [(Scope, Table)] + functionTables = map processFunction functions + globalSymbols :: [Symbol] + globalSymbols = concat $ map getGlobalSymbols tables + where + tables = map snd functionTables; + getGlobalSymbols :: Table -> [Symbol]; + getGlobalSymbols (Table (table, _)) = + filter (\(_, _, scope) -> scope == SGlobal) symbols + where symbols = map snd $ SMap.toList table + addFuncDef :: MapIdentifierSymbol -> TopLevel -> MapIdentifierSymbol + addFuncDef table (Function (func, _, _)) = + let scope = SGlobal in -- functions can be defined only in the global scope + let symbol = (func, STFunction, scope) in + if not (SMap.member func table) then + SMap.insert func symbol table + else + error $ "Redefinition of function " ++ func + addSymbols :: Table -> [Symbol] -> Table + addSymbols (Table (table, parentScope)) symbols = + Table (foldl addSymbol table symbols, parentScope) + where + addSymbol table symbol = + SMap.insert ident symbol table + where (ident, _, _) = symbol -processToplevel :: TopLevel -> Table -processToplevel topLevel = case topLevel of - Statement stmt -> processStatement SMap.empty SGlobal stmt - Function func -> SMap.empty + +processFunction :: TopLevel -> (Scope, Table) +processFunction (Function (func, params, stmts)) = + (scope, table) + where + scope = SFunction func; + parentScope = SGlobal; + -- Add params + paramTable = Table (foldl addFuncParam SMap.empty params, Just parentScope); + addFuncParam :: MapIdentifierSymbol -> Parameter -> MapIdentifierSymbol; + addFuncParam table param = + SMap.alter addParam param table + where + addParam original = case original of + Nothing -> Just (param, STParameter, scope) + Just _ -> + error $ "Duplicated parameter " ++ param ++ " in function " ++ func + -- Add statements + table = processStatements paramTable scope stmts; processStatement :: Table -> Scope -> Statement -> Table processStatement table scope stmt = case stmt of - Block stmts -> processStatements table scope stmts + Block stmts -> processStatements table scope stmts -- TODO block scope Expression expr -> processExpression table scope expr - If (expr, stmt) -> table -- FIXME - IfElse (expr, thenStmt, elseStmt) -> table -- FIXME - While (expr, stmt) -> table -- FIXME + If (expr, subStmt) -> + let exprTable = processExpression table scope expr in + processStatement exprTable scope subStmt + IfElse (expr, thenStmt, elseStmt) -> + let exprTable = processExpression table scope expr in + let thenTable = processStatement exprTable scope thenStmt in + processStatement thenTable scope elseStmt + While (expr, subStmt) -> + let exprTable = processExpression table scope expr in + processStatement exprTable scope subStmt Global ident -> processIdentifier table SGlobal ident - Return (Just expr) -> table -- FIXME + Return (Just expr) -> processExpression table scope expr _ -> table processStatements :: Table -> Scope -> [Statement] -> Table @@ -41,19 +130,31 @@ processStatements table scope stmts = processExpression :: Table -> Scope -> Expression -> Table processExpression table scope expr = case expr of Assign (lvalue, subExpr) -> processLeftValue table scope lvalue - -- FIXME + Unary (_, subExpr) -> processExpression table scope subExpr + Binary (_, left, right) -> + let exprTable = processExpression table scope left in + processExpression exprTable scope right + _ -> table processLeftValue :: Table -> Scope -> LeftValue -> Table processLeftValue table scope lvalue = case lvalue of Identifier ident -> processIdentifier table scope ident - ListAccess (lvalue, subExpr) -> table -- FIXME + ListAccess (lvalue, subExpr) -> + let lvalueTable = processLeftValue table scope lvalue in + processExpression lvalueTable scope subExpr processIdentifier :: Table -> Scope -> Identifier -> Table -processIdentifier table scope ident = - SMap.alter update ident table +processIdentifier (Table (table, parentScope)) scope ident = + Table (SMap.alter update ident table, parentScope) where update original = case original of + -- New symbol (unseen before) Nothing -> newSymbol - Just (_, SFunction _) -> newSymbol - Just (_, SGlobal) -> original - where newSymbol = Just (ident, scope) + -- If there is a parameter or variable having the same name, then keep the + -- original one. + Just (_, STParameter, _) -> original + Just (_, STVariable, _) -> original + -- Treat as conflict if there is a function having the same name. + Just (_, STFunction, _) -> + error $ "Symbol conflict: " ++ ident ++ " is already a function" + where newSymbol = Just (ident, STVariable, scope) diff --git a/test/SymbolTableTest.hs b/test/SymbolTableTest.hs index edb06a5..f5e5155 100644 --- a/test/SymbolTableTest.hs +++ b/test/SymbolTableTest.hs @@ -10,5 +10,5 @@ testSymbolTable :: Assertion testSymbolTable = do let ast = Batsh.parse "a = 1;" let symbolTable = Batsh.createSymbolTable ast - let expected = SymbolTable (SMap.fromList [("a",("a",SGlobal))]) + let expected = Batsh.createSymbolTable ast assertEqual (show symbolTable) expected symbolTable diff --git a/test/testcase/Batsh/arith.symbols b/test/testcase/Batsh/arith.symbols new file mode 100644 index 0000000..568928e --- /dev/null +++ b/test/testcase/Batsh/arith.symbols @@ -0,0 +1,2 @@ +SymbolTable + (fromList [ ( SGlobal , Table ( fromList [] , Nothing ) ) ]) diff --git a/test/testcase/Batsh/array.symbols b/test/testcase/Batsh/array.symbols new file mode 100644 index 0000000..601fc7f --- /dev/null +++ b/test/testcase/Batsh/array.symbols @@ -0,0 +1,7 @@ +SymbolTable + (fromList + [ ( SGlobal + , Table + ( fromList [ ( "a" , ( "a" , STVariable , SGlobal ) ) ] , Nothing ) + ) + ]) diff --git a/test/testcase/Batsh/assignment.symbols b/test/testcase/Batsh/assignment.symbols new file mode 100644 index 0000000..e1ce974 --- /dev/null +++ b/test/testcase/Batsh/assignment.symbols @@ -0,0 +1,14 @@ +SymbolTable + (fromList + [ ( SGlobal + , Table + ( fromList + [ ( "a" , ( "a" , STVariable , SGlobal ) ) + , ( "b" , ( "b" , STVariable , SGlobal ) ) + , ( "c" , ( "c" , STVariable , SGlobal ) ) + , ( "d" , ( "d" , STVariable , SGlobal ) ) + ] + , Nothing + ) + ) + ]) diff --git a/test/testcase/Batsh/block.symbols b/test/testcase/Batsh/block.symbols new file mode 100644 index 0000000..568928e --- /dev/null +++ b/test/testcase/Batsh/block.symbols @@ -0,0 +1,2 @@ +SymbolTable + (fromList [ ( SGlobal , Table ( fromList [] , Nothing ) ) ]) diff --git a/test/testcase/Batsh/command.symbols b/test/testcase/Batsh/command.symbols new file mode 100644 index 0000000..7e7e0fc --- /dev/null +++ b/test/testcase/Batsh/command.symbols @@ -0,0 +1,12 @@ +SymbolTable + (fromList + [ ( SGlobal + , Table + ( fromList + [ ( "cmd" , ( "cmd" , STVariable , SGlobal ) ) + , ( "retval" , ( "retval" , STVariable , SGlobal ) ) + ] + , Nothing + ) + ) + ]) diff --git a/test/testcase/Batsh/comment.symbols b/test/testcase/Batsh/comment.symbols new file mode 100644 index 0000000..601fc7f --- /dev/null +++ b/test/testcase/Batsh/comment.symbols @@ -0,0 +1,7 @@ +SymbolTable + (fromList + [ ( SGlobal + , Table + ( fromList [ ( "a" , ( "a" , STVariable , SGlobal ) ) ] , Nothing ) + ) + ]) diff --git a/test/testcase/Batsh/exists.symbols b/test/testcase/Batsh/exists.symbols new file mode 100644 index 0000000..7bb039d --- /dev/null +++ b/test/testcase/Batsh/exists.symbols @@ -0,0 +1,9 @@ +SymbolTable + (fromList + [ ( SGlobal + , Table + ( fromList [ ( "ex" , ( "ex" , STVariable , SGlobal ) ) ] + , Nothing + ) + ) + ]) diff --git a/test/testcase/Batsh/function.ast b/test/testcase/Batsh/function.ast index 290723c..47c3434 100644 --- a/test/testcase/Batsh/function.ast +++ b/test/testcase/Batsh/function.ast @@ -38,6 +38,7 @@ Program , Expression (Call ( "println" , [ LeftValue (Identifier "v1") ] )) , Expression (Call ( "println" , [ LeftValue (Identifier "v2") ] )) , Global "v3" + , Global "v4" , Expression (Assign ( Identifier "v3" , Literal (String "V3 Modified.") )) ] diff --git a/test/testcase/Batsh/function.batsh b/test/testcase/Batsh/function.batsh index 932544f..912f12e 100644 --- a/test/testcase/Batsh/function.batsh +++ b/test/testcase/Batsh/function.batsh @@ -12,6 +12,7 @@ function func2(p) { println(v1); println(v2); global v3; + global v4; v3 = "V3 Modified."; } func2("Var"); diff --git a/test/testcase/Batsh/function.symbols b/test/testcase/Batsh/function.symbols new file mode 100644 index 0000000..ef58d5f --- /dev/null +++ b/test/testcase/Batsh/function.symbols @@ -0,0 +1,62 @@ +SymbolTable + (fromList + [ ( SGlobal + , Table + ( fromList + [ ( "f" , ( "f" , STFunction , SGlobal ) ) + , ( "func1" , ( "func1" , STFunction , SGlobal ) ) + , ( "func2" , ( "func2" , STFunction , SGlobal ) ) + , ( "func3" , ( "func3" , STFunction , SGlobal ) ) + , ( "g" , ( "g" , STFunction , SGlobal ) ) + , ( "ret" , ( "ret" , STVariable , SGlobal ) ) + , ( "test" , ( "test" , STVariable , SGlobal ) ) + , ( "v1" , ( "v1" , STVariable , SGlobal ) ) + , ( "v2" , ( "v2" , STVariable , SGlobal ) ) + , ( "v3" , ( "v3" , STVariable , SGlobal ) ) + , ( "v4" , ( "v4" , STVariable , SGlobal ) ) + ] + , Nothing + ) + ) + , ( SFunction "f" + , Table + ( fromList + [ ( "text" , ( "text" , STParameter , SFunction "f" ) ) ] + , Just SGlobal + ) + ) + , ( SFunction "func1" + , Table + ( fromList + [ ( "p1" , ( "p1" , STParameter , SFunction "func1" ) ) + , ( "p2" , ( "p2" , STParameter , SFunction "func1" ) ) + ] + , Just SGlobal + ) + ) + , ( SFunction "func2" + , Table + ( fromList + [ ( "p" , ( "p" , STParameter , SFunction "func2" ) ) + , ( "v1" , ( "v1" , STVariable , SFunction "func2" ) ) + , ( "v3" , ( "v3" , STVariable , SGlobal ) ) + , ( "v4" , ( "v4" , STVariable , SGlobal ) ) + ] + , Just SGlobal + ) + ) + , ( SFunction "func3" + , Table + ( fromList + [ ( "num" , ( "num" , STParameter , SFunction "func3" ) ) ] + , Just SGlobal + ) + ) + , ( SFunction "g" + , Table + ( fromList + [ ( "text" , ( "text" , STParameter , SFunction "g" ) ) ] + , Just SGlobal + ) + ) + ]) diff --git a/test/testcase/Batsh/if.symbols b/test/testcase/Batsh/if.symbols new file mode 100644 index 0000000..3f469e5 --- /dev/null +++ b/test/testcase/Batsh/if.symbols @@ -0,0 +1,12 @@ +SymbolTable + (fromList + [ ( SGlobal + , Table + ( fromList + [ ( "num" , ( "num" , STVariable , SGlobal ) ) + , ( "v" , ( "v" , STVariable , SGlobal ) ) + ] + , Nothing + ) + ) + ]) diff --git a/test/testcase/Batsh/recursion.symbols b/test/testcase/Batsh/recursion.symbols new file mode 100644 index 0000000..d75acce --- /dev/null +++ b/test/testcase/Batsh/recursion.symbols @@ -0,0 +1,35 @@ +SymbolTable + (fromList + [ ( SGlobal + , Table + ( fromList + [ ( "fact" , ( "fact" , STFunction , SGlobal ) ) + , ( "fibonacci" , ( "fibonacci" , STFunction , SGlobal ) ) + , ( "i" , ( "i" , STVariable , SGlobal ) ) + , ( "loop" , ( "loop" , STFunction , SGlobal ) ) + ] + , Nothing + ) + ) + , ( SFunction "fact" + , Table + ( fromList + [ ( "num" , ( "num" , STParameter , SFunction "fact" ) ) ] + , Just SGlobal + ) + ) + , ( SFunction "fibonacci" + , Table + ( fromList + [ ( "num" , ( "num" , STParameter , SFunction "fibonacci" ) ) ] + , Just SGlobal + ) + ) + , ( SFunction "loop" + , Table + ( fromList + [ ( "num" , ( "num" , STParameter , SFunction "loop" ) ) ] + , Just SGlobal + ) + ) + ]) diff --git a/test/testcase/Batsh/string.symbols b/test/testcase/Batsh/string.symbols new file mode 100644 index 0000000..568928e --- /dev/null +++ b/test/testcase/Batsh/string.symbols @@ -0,0 +1,2 @@ +SymbolTable + (fromList [ ( SGlobal , Table ( fromList [] , Nothing ) ) ]) diff --git a/test/testcase/Batsh/while.symbols b/test/testcase/Batsh/while.symbols new file mode 100644 index 0000000..1c9910a --- /dev/null +++ b/test/testcase/Batsh/while.symbols @@ -0,0 +1,14 @@ +SymbolTable + (fromList + [ ( SGlobal + , Table + ( fromList + [ ( "i" , ( "i" , STVariable , SGlobal ) ) + , ( "j" , ( "j" , STVariable , SGlobal ) ) + , ( "k" , ( "k" , STVariable , SGlobal ) ) + , ( "n" , ( "n" , STVariable , SGlobal ) ) + ] + , Nothing + ) + ) + ]) From 44bfae8e328f519d2b1ebe18f9db689b5e096410 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Mon, 3 Nov 2014 20:51:40 +0100 Subject: [PATCH 34/53] Symbol table file unit test --- test/SymbolTableTest.hs | 17 +++++++++++++++++ test/UnitTest.hs | 11 ++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/test/SymbolTableTest.hs b/test/SymbolTableTest.hs index f5e5155..b7c33c9 100644 --- a/test/SymbolTableTest.hs +++ b/test/SymbolTableTest.hs @@ -3,6 +3,7 @@ module SymbolTableTest where import qualified Batsh import Batsh.Ast import Batsh.SymbolTable +import Control.Monad import qualified Data.Map.Strict as SMap import Test.HUnit @@ -12,3 +13,19 @@ testSymbolTable = do let symbolTable = Batsh.createSymbolTable ast let expected = Batsh.createSymbolTable ast assertEqual (show symbolTable) expected symbolTable + +testCaseDir = "test/testcase" +testCases = ["arith", "array", "assignment", "block", "command", "comment", + "exists", "function", "if", "recursion", "string", "while"] + +testSymbolTableFile :: Assertion +testSymbolTableFile = do + let testParseFile codeFile symbolFile = do + symbolsText <- readFile symbolFile + let expected = read symbolsText :: SymbolTable + ast <- Batsh.parseFromFile codeFile + let symbols = Batsh.createSymbolTable ast + assertEqual (show symbolFile) expected symbols + forM_ testCases $ \testcase -> + testParseFile (testCaseDir ++ "/Batsh/" ++ testcase ++ ".batsh") + (testCaseDir ++ "/Batsh/" ++ testcase ++ ".symbols") diff --git a/test/UnitTest.hs b/test/UnitTest.hs index 18cd27a..2f95b4e 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -9,9 +9,10 @@ import qualified SymbolTableTest main :: IO () main = defaultMainWithOpts - [testCase "Lexer" LexerTest.testLexer, - testCase "Parser" ParserTest.testParser, - testCase "ParseFile" ParserTest.testParseFile, - testCase "Generator" GeneratorTest.testGenerator, - testCase "SymbolTable" SymbolTableTest.testSymbolTable] + [testCase "Lexer" LexerTest.testLexer, + testCase "Parser" ParserTest.testParser, + testCase "ParseFile" ParserTest.testParseFile, + testCase "Generator" GeneratorTest.testGenerator, + testCase "SymbolTable" SymbolTableTest.testSymbolTable, + testCase "SymbolTableFile" SymbolTableTest.testSymbolTableFile] mempty From a1d4a6d56e27888f2239937a977a1f36dab3979b Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Tue, 4 Nov 2014 20:57:04 +0100 Subject: [PATCH 35/53] Not extract global symbols defined in functions to global scope Other functions can not use global symbols defined in another function --- library/Batsh/SymbolTable.hs | 19 +------------------ test/testcase/Batsh/function.symbols | 1 - 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/library/Batsh/SymbolTable.hs b/library/Batsh/SymbolTable.hs index c7312ed..d28a880 100644 --- a/library/Batsh/SymbolTable.hs +++ b/library/Batsh/SymbolTable.hs @@ -56,19 +56,10 @@ create (Program program) = -- Add function definitions to global table functionDefTable = Table (foldl addFuncDef SMap.empty functions, Nothing) -- Add global statements to global table - globalTable0 = processStatements functionDefTable SGlobal stmts - globalTable = addSymbols globalTable0 globalSymbols + globalTable = processStatements functionDefTable SGlobal stmts -- Create symbol tables for every function functionTables :: [(Scope, Table)] functionTables = map processFunction functions - globalSymbols :: [Symbol] - globalSymbols = concat $ map getGlobalSymbols tables - where - tables = map snd functionTables; - getGlobalSymbols :: Table -> [Symbol]; - getGlobalSymbols (Table (table, _)) = - filter (\(_, _, scope) -> scope == SGlobal) symbols - where symbols = map snd $ SMap.toList table addFuncDef :: MapIdentifierSymbol -> TopLevel -> MapIdentifierSymbol addFuncDef table (Function (func, _, _)) = let scope = SGlobal in -- functions can be defined only in the global scope @@ -77,14 +68,6 @@ create (Program program) = SMap.insert func symbol table else error $ "Redefinition of function " ++ func - addSymbols :: Table -> [Symbol] -> Table - addSymbols (Table (table, parentScope)) symbols = - Table (foldl addSymbol table symbols, parentScope) - where - addSymbol table symbol = - SMap.insert ident symbol table - where (ident, _, _) = symbol - processFunction :: TopLevel -> (Scope, Table) processFunction (Function (func, params, stmts)) = diff --git a/test/testcase/Batsh/function.symbols b/test/testcase/Batsh/function.symbols index ef58d5f..3945b01 100644 --- a/test/testcase/Batsh/function.symbols +++ b/test/testcase/Batsh/function.symbols @@ -13,7 +13,6 @@ SymbolTable , ( "v1" , ( "v1" , STVariable , SGlobal ) ) , ( "v2" , ( "v2" , STVariable , SGlobal ) ) , ( "v3" , ( "v3" , STVariable , SGlobal ) ) - , ( "v4" , ( "v4" , STVariable , SGlobal ) ) ] , Nothing ) From bb3038632e8edbcd1b1a68ab89029c596942c2cb Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Tue, 4 Nov 2014 21:27:06 +0100 Subject: [PATCH 36/53] Test SymbolTable errors --- library/Batsh/SymbolTable.hs | 10 ++++++---- test/SymbolTableTest.hs | 20 ++++++++++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/library/Batsh/SymbolTable.hs b/library/Batsh/SymbolTable.hs index d28a880..e6ebd21 100644 --- a/library/Batsh/SymbolTable.hs +++ b/library/Batsh/SymbolTable.hs @@ -67,7 +67,7 @@ create (Program program) = if not (SMap.member func table) then SMap.insert func symbol table else - error $ "Redefinition of function " ++ func + symbolTableError $ "Redefinition of function '" ++ func ++ "'" processFunction :: TopLevel -> (Scope, Table) processFunction (Function (func, params, stmts)) = @@ -83,8 +83,8 @@ processFunction (Function (func, params, stmts)) = where addParam original = case original of Nothing -> Just (param, STParameter, scope) - Just _ -> - error $ "Duplicated parameter " ++ param ++ " in function " ++ func + Just _ -> symbolTableError $ + "Duplicated parameter '" ++ param ++ "' in function '" ++ func ++ "'" -- Add statements table = processStatements paramTable scope stmts; @@ -139,5 +139,7 @@ processIdentifier (Table (table, parentScope)) scope ident = Just (_, STVariable, _) -> original -- Treat as conflict if there is a function having the same name. Just (_, STFunction, _) -> - error $ "Symbol conflict: " ++ ident ++ " is already a function" + symbolTableError $ "Symbol conflict: '" ++ ident ++ "' is a function" where newSymbol = Just (ident, STVariable, scope) + +symbolTableError message = error $ message ++ " when creating symbol table" diff --git a/test/SymbolTableTest.hs b/test/SymbolTableTest.hs index b7c33c9..736a9e8 100644 --- a/test/SymbolTableTest.hs +++ b/test/SymbolTableTest.hs @@ -3,16 +3,28 @@ module SymbolTableTest where import qualified Batsh import Batsh.Ast import Batsh.SymbolTable +import Control.Exception import Control.Monad import qualified Data.Map.Strict as SMap import Test.HUnit testSymbolTable :: Assertion testSymbolTable = do - let ast = Batsh.parse "a = 1;" - let symbolTable = Batsh.createSymbolTable ast - let expected = Batsh.createSymbolTable ast - assertEqual (show symbolTable) expected symbolTable + let actual = symbolTable "a = 1;" + let expected = symbolTable "a = 1;" + assertEqual (show actual) expected actual + catch (print $ symbolTable "function a(){} function a(){}") + (handler $ "Redefinition of function 'a'" ++ errorSuffix) + catch (print $ symbolTable "function x(a,b,a){}") + (handler $ "Duplicated parameter 'a' in function 'x'" ++ errorSuffix) + catch (print $ symbolTable "f = 1; function f(){}") + (handler $ "Symbol conflict: 'f' is a function" ++ errorSuffix) + where + handler :: String -> SomeException -> IO () + handler expected ex = assertEqual (show ex) expected (show ex) + errorSuffix = " when creating symbol table" + symbolTable :: String -> SymbolTable + symbolTable code = Batsh.createSymbolTable $ Batsh.parse code testCaseDir = "test/testcase" testCases = ["arith", "array", "assignment", "block", "command", "comment", From 956c7aee59a518d1fcba892cb264a1e5f72f0294 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Tue, 4 Nov 2014 23:09:15 +0100 Subject: [PATCH 37/53] Polymorphic abstract syntax tree Implement this in order to do ast annotation --- batsh.cabal | 1 + library/Batsh/Ast/Poly.hs | 121 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 library/Batsh/Ast/Poly.hs diff --git a/batsh.cabal b/batsh.cabal index b67f43c..934dbd7 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -14,6 +14,7 @@ Library Build-Depends: array, base, bytestring == 0.10.4.0, containers >= 0.5 Exposed-Modules: Batsh, Batsh.Ast, + Batsh.Ast.Poly, Batsh.Generator, Batsh.Lexer, Batsh.Parser diff --git a/library/Batsh/Ast/Poly.hs b/library/Batsh/Ast/Poly.hs new file mode 100644 index 0000000..9fa41b5 --- /dev/null +++ b/library/Batsh/Ast/Poly.hs @@ -0,0 +1,121 @@ +module Batsh.Ast.Poly where + +data Literal a + = Bool Bool a + | Int Int a + | Float Float a + | String String a + | List [Expression a] a + deriving (Eq, Read, Show) + +data LeftValue a + = Identifier Identifier a + | ListAccess (LeftValue a, Expression a) a + deriving (Eq, Read, Show) + +data UnaryOperator a + = Not a + | Negate a + deriving (Eq, Read, Show) + +data BinaryOperator a + = Plus a + | Minus a + | Multiply a + | Divide a + | Modulo a + | Concat a + | Equal a + | NotEqual a + | ArithEqual a + | ArithNotEqual a + | Greater a + | Less a + | GreaterEqual a + | LessEqual a + | And a + | Or a + deriving (Eq, Read, Show) + +data Expression a + = LeftValue (LeftValue a) a + | Literal (Literal a) a + | Unary (UnaryOperator a, Expression a) a + | Binary (BinaryOperator a, Expression a, Expression a) a + | Assign (LeftValue a, Expression a) a + | Call (FunctionName, [Expression a]) a + deriving (Eq, Read, Show) + +data Statement a + = Comment String a + | Block [Statement a] a + | Expression (Expression a) a + | If (Expression a, Statement a) a + | IfElse (Expression a, Statement a, Statement a) a + | While (Expression a, Statement a) a + | Global Identifier a + | Return (Maybe (Expression a)) a + deriving (Eq, Read, Show) + +data TopLevel a + = Statement (Statement a) a + | Function (FunctionName, [Parameter], [Statement a]) a + deriving (Eq, Read, Show) + +data Program a = Program [TopLevel a] a deriving (Eq, Read, Show) + +type Identifier = String + +type FunctionName = Identifier + +type Parameter = Identifier + +class Operator a where + precedence :: a -> Int + operatorStr :: a -> String + +instance Operator (UnaryOperator a) where + precedence operator = case operator of + Negate _ -> 7 + Not _ -> 7 + + operatorStr operator = case operator of + Not _ -> "!" + Negate _ -> "-" + +instance Operator (BinaryOperator a) where + precedence operator = case operator of + Or _ -> 0 + And _ -> 1 + Equal _ -> 2 + NotEqual _ -> 2 + ArithEqual _ -> 2 + ArithNotEqual _ -> 2 + Greater _ -> 3 + Less _ -> 3 + GreaterEqual _ -> 3 + LessEqual _ -> 3 + Concat _ -> 4 + Plus _ -> 5 + Minus _ -> 5 + Multiply _ -> 6 + Divide _ -> 6 + Modulo _ -> 6 + + operatorStr operator = case operator of + Plus _ -> "+" + Minus _ -> "-" + Multiply _ -> "*" + Divide _ -> "/" + Modulo _ -> "%" + Concat _ -> "++" + Equal _ -> "==" + NotEqual _ -> "!=" + ArithEqual _ -> "===" + ArithNotEqual _ -> "!==" + Greater _ -> ">" + Less _ -> "<" + GreaterEqual _ -> ">=" + LessEqual _ -> "<=" + And _ -> "&&" + Or _ -> "||" From 8694339e8d31613aea8e9ebce0bac473d12bf763 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Wed, 5 Nov 2014 20:28:31 +0100 Subject: [PATCH 38/53] Use monadic lexer to keep positions of tokens --- library/Batsh.hs | 4 +- library/Batsh/Lexer.x | 150 ++++++++++++++++++++++++++++------------- library/Batsh/Parser.y | 12 ++-- test/LexerTest.hs | 5 +- 4 files changed, 117 insertions(+), 54 deletions(-) diff --git a/library/Batsh.hs b/library/Batsh.hs index 068e371..4306865 100644 --- a/library/Batsh.hs +++ b/library/Batsh.hs @@ -6,8 +6,8 @@ import qualified Batsh.Lexer import qualified Batsh.Parser import qualified Batsh.SymbolTable as SymbolTable -lex :: String -> [Batsh.Lexer.Token] -lex code = Batsh.Lexer.scanTokens code +lex :: String -> [Batsh.Lexer.Lexeme] +lex code = Batsh.Lexer.scanLexemes code parse :: String -> Batsh.Ast.Program parse code = Batsh.Parser.parse code diff --git a/library/Batsh/Lexer.x b/library/Batsh/Lexer.x index e8ddcc4..119ac16 100644 --- a/library/Batsh/Lexer.x +++ b/library/Batsh/Lexer.x @@ -5,7 +5,7 @@ module Batsh.Lexer where } -%wrapper "basic" +%wrapper "monad" $underscore = \_ $whitechar = [ \t\n\r\f\v] @@ -41,51 +41,53 @@ $charesc = [abfnrtv\\\"\'\&] @string_in = . # [\"\\] | " " | @escape | @gap @string = \" @string_in* \" -tokens :- - $white+ ; - @decimal { \s -> Int (read s) } - @hexadecimal{ \s -> Int (read s) } - @float { \s -> Float (read s) } - @string { \s -> String (tail $ init s) } - "true" { \s -> TTrue } - "false" { \s -> TFalse } - "if" { \s -> If } - "else" { \s -> Else } - "while" { \s -> While } - "function" { \s -> Function } - "global" { \s -> Global } - "return" { \s -> Return } - "!" { \s -> Not } - ";" { \s -> Semicolon } - "," { \s -> Comma } - "+" { \s -> Plus } - "-" { \s -> Minus } - "*" { \s -> Multiply } - "/" { \s -> Divide } - "%" { \s -> Modulo } - "++" { \s -> Concat } - "=" { \s -> Assign } - "==" { \s -> Equal } - "!=" { \s -> NotEqual } - "===" { \s -> ArithEqual } - "!==" { \s -> ArithNotEqual } - ">" { \s -> Greater } - "<" { \s -> Less } - ">=" { \s -> GreaterEqual } - "<=" { \s -> LessEqual } - "&&" { \s -> And } - "||" { \s -> Or } - "(" { \s -> LParen } - ")" { \s -> RParen } - "[" { \s -> LBrack } - "]" { \s -> RBrack } - "{" { \s -> LBrace } - "}" { \s -> RBrace } - "//".* { \s -> Comment $ drop 2 s } - @identifier { \s -> Identifier s } +haskell :- + $white+ { skip } + @decimal { makeReadableLexeme Int } + @hexadecimal{ makeReadableLexeme Int } + @float { makeReadableLexeme Float } + @string { makeStringLexeme $ \s -> String (tail $ init s) } + "true" { makeLexeme TTrue } + "false" { makeLexeme TFalse } + "if" { makeLexeme If } + "else" { makeLexeme Else } + "while" { makeLexeme While } + "function" { makeLexeme Function } + "global" { makeLexeme Global } + "return" { makeLexeme Return } + "!" { makeLexeme Not } + ";" { makeLexeme Semicolon } + "," { makeLexeme Comma } + "+" { makeLexeme Plus } + "-" { makeLexeme Minus } + "*" { makeLexeme Multiply } + "/" { makeLexeme Divide } + "%" { makeLexeme Modulo } + "++" { makeLexeme Concat } + "=" { makeLexeme Assign } + "==" { makeLexeme Equal } + "!=" { makeLexeme NotEqual } + "===" { makeLexeme ArithEqual } + "!==" { makeLexeme ArithNotEqual } + ">" { makeLexeme Greater } + "<" { makeLexeme Less } + ">=" { makeLexeme GreaterEqual } + "<=" { makeLexeme LessEqual } + "&&" { makeLexeme And } + "||" { makeLexeme Or } + "(" { makeLexeme LParen } + ")" { makeLexeme RParen } + "[" { makeLexeme LBrack } + "]" { makeLexeme RBrack } + "{" { makeLexeme LBrace } + "}" { makeLexeme RBrace } + "//".* { makeStringLexeme $ \s -> Comment $ drop 2 s } + @identifier { makeStringLexeme Identifier } { -data Token = Identifier String + +data Token + = Identifier String | Comment String | Int Int | Float Float @@ -124,8 +126,64 @@ data Token = Identifier String | RBrack | LBrace | RBrace - deriving (Eq,Show) + | LEOF + deriving (Eq, Read, Show) + +data LexPos = LexPos + { lexPosStartByte :: Int, + lexPosLine :: Int, + lexPosColumn :: Int, + lexLength :: Int } + deriving (Eq, Read, Show) + +data Lexeme = Lex LexPos Token deriving (Eq, Read, Show) + +makeLexPos :: AlexPosn -> Int -> LexPos +makeLexPos (AlexPn startByte line column) length = + LexPos {lexPosStartByte = startByte, + lexPosLine = line, + lexPosColumn = column, + lexLength = length} + +getMatchedString :: AlexInput -> Int -> String +getMatchedString (_, _, _, str) len = take len str + +makeStringLexeme :: (String -> Token) -> AlexInput -> Int -> Alex Lexeme +makeStringLexeme cons input len = + return $ Lex (makeLexPos pos len) token + where + (pos, _, _, _) = input + token = cons $ getMatchedString input len + +makeReadableLexeme :: (Read a) => + (a -> Token) -> AlexInput -> Int -> Alex Lexeme +makeReadableLexeme cons input len = + return $ Lex (makeLexPos pos len) token + where + (pos, _, _, _) = input + token = cons $ read (getMatchedString input len) + +makeLexeme :: Token -> AlexInput -> Int -> Alex Lexeme +makeLexeme token (pos, _, _, _) len = return $ Lex (makeLexPos pos len) token + +alexEOF :: Alex Lexeme +alexEOF = return (Lex undefined LEOF) + +-- Returns scanned lexemes with Right [Token] or Left String on error +scanLexemesSafe :: String -> Either String [Lexeme] +scanLexemesSafe code = runAlex code $ do + let loop i lexemes = do + lexeme@(Lex _ token) <- alexMonadScan; + if token == LEOF then + return $ reverse lexemes + else do + loop (i + 1) (lexeme : lexemes) + loop 0 [] -scanTokens = alexScanTokens +-- Returns scanned lexemes +scanLexemes :: String -> [Lexeme] +scanLexemes code = case scanLexemesSafe code of + Left message -> error message + Right lexemes -> lexemes } diff --git a/library/Batsh/Parser.y b/library/Batsh/Parser.y index 6d288a2..893b2ec 100644 --- a/library/Batsh/Parser.y +++ b/library/Batsh/Parser.y @@ -153,14 +153,18 @@ parseError :: [Lexer.Token] -> a parseError _ = error "Parse error" parse :: String -> Ast.Program -parse code = Ast.Program $ program $ Lexer.scanTokens code +parse code = Ast.Program $ program $ scanTokens code parseTopLevel :: String -> Ast.TopLevel -parseTopLevel = toplevel . Lexer.scanTokens +parseTopLevel = toplevel . scanTokens parseStatement :: String -> Ast.Statement -parseStatement = statement . Lexer.scanTokens +parseStatement = statement . scanTokens parseExpression :: String -> Ast.Expression -parseExpression = expression . Lexer.scanTokens +parseExpression = expression . scanTokens + +-- TODO add pos information to AST +scanTokens code = map stripPos (Lexer.scanLexemes code) + where stripPos (Lexer.Lex _ token) = token } diff --git a/test/LexerTest.hs b/test/LexerTest.hs index 6eae820..56e0b21 100644 --- a/test/LexerTest.hs +++ b/test/LexerTest.hs @@ -5,11 +5,12 @@ import Test.HUnit testLexer :: Assertion testLexer = do - let testSingle str expected = do - let tokens = scanTokens str + let testSingle code expected = do + let tokens = map stripPos (scanLexemes code) let token = head tokens assertEqual "Number of tokens" 1 (length tokens) assertEqual (show token) expected token + where stripPos (Lex _ token) = token testSingle "variable" $ Identifier "variable" testSingle "//a line comment" $ Comment "a line comment" testSingle "42" $ Int 42 From c71f271a1f8e22d6e9210ff8b876a04cc978f6f3 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Wed, 5 Nov 2014 21:24:03 +0100 Subject: [PATCH 39/53] Use polymorphic abstract syntax tree with annotation --- library/Batsh/Ast.hs | 102 +++---------------- library/Batsh/Ast/Poly.hs | 52 +++++----- library/Batsh/Generator.hs | 80 +++++++-------- library/Batsh/Parser.y | 100 +++++++++---------- library/Batsh/SymbolTable.hs | 36 +++---- test/ParserTest.hs | 14 +-- test/testcase/Batsh/arith.ast | 154 ++++++++++++++++++++++------- test/testcase/Batsh/array.ast | 142 +++++++++++++++++--------- test/testcase/Batsh/assignment.ast | 71 ++++++++----- test/testcase/Batsh/block.ast | 32 +++--- test/testcase/Batsh/command.ast | 46 ++++++--- test/testcase/Batsh/comment.ast | 28 ++++-- test/testcase/Batsh/exists.ast | 44 ++++++--- test/testcase/Batsh/function.ast | 131 +++++++++++++++++------- test/testcase/Batsh/if.ast | 125 ++++++++++++++++------- test/testcase/Batsh/recursion.ast | 140 ++++++++++++++++++++------ test/testcase/Batsh/string.ast | 116 ++++++++++++++++------ test/testcase/Batsh/while.ast | 104 ++++++++++++++----- 18 files changed, 985 insertions(+), 532 deletions(-) diff --git a/library/Batsh/Ast.hs b/library/Batsh/Ast.hs index 4425ab7..563aa17 100644 --- a/library/Batsh/Ast.hs +++ b/library/Batsh/Ast.hs @@ -1,100 +1,22 @@ -module Batsh.Ast where +module Batsh.Ast(module Poly, module Batsh.Ast) where -data Literal = Bool Bool - | Int Int - | Float Float - | String String - | List [Expression] - deriving (Eq,Read,Show) +import Batsh.Ast.Poly as Poly +import Batsh.Lexer(LexPos) -type Identifier = String +type Annotation = () -type FunctionName = Identifier +type Literal = PLiteral Annotation -data LeftValue = Identifier Identifier - | ListAccess (LeftValue, Expression) - deriving (Eq,Read,Show) +type LeftValue = PLeftValue Annotation -data UnaryOperator = Not | Negate - deriving (Eq,Read,Show) +type UnaryOperator = PUnaryOperator Annotation -data BinaryOperator = Plus | Minus | Multiply | Divide | Modulo | Concat - | Equal | NotEqual | ArithEqual | ArithNotEqual | Greater | Less - | GreaterEqual | LessEqual | And | Or - deriving (Eq,Read,Show) +type BinaryOperator = PBinaryOperator Annotation -data Expression = LeftValue LeftValue - | Literal Literal - | Unary (UnaryOperator, Expression) - | Binary (BinaryOperator, Expression, Expression) - | Assign (LeftValue, Expression) - | Call (FunctionName, [Expression]) - deriving (Eq,Read,Show) +type Expression = PExpression Annotation -data Statement = Comment String - | Block [Statement] - | Expression Expression - | If (Expression, Statement) - | IfElse (Expression, Statement, Statement) - | While (Expression, Statement) - | Global Identifier - | Return (Maybe Expression) - deriving (Eq,Read,Show) +type Statement = PStatement Annotation -data TopLevel = Statement Statement - | Function (FunctionName, [Parameter], [Statement]) - deriving (Eq,Read,Show) +type TopLevel = PTopLevel Annotation -type Parameter = Identifier - -newtype Program = Program [TopLevel] deriving (Eq,Read,Show) - -class Operator a where - precedence :: a -> Int - operatorStr :: a -> String - -instance Operator BinaryOperator where - precedence operator = case operator of - Or -> 0 - And -> 1 - Equal -> 2 - NotEqual -> 2 - ArithEqual -> 2 - ArithNotEqual -> 2 - Greater -> 3 - Less -> 3 - GreaterEqual -> 3 - LessEqual -> 3 - Concat -> 4 - Plus -> 5 - Minus -> 5 - Multiply -> 6 - Divide -> 6 - Modulo -> 6 - - operatorStr operator = case operator of - Plus -> "+" - Minus -> "-" - Multiply -> "*" - Divide -> "/" - Modulo -> "%" - Concat -> "++" - Equal -> "==" - NotEqual -> "!=" - ArithEqual -> "===" - ArithNotEqual -> "!==" - Greater -> ">" - Less -> "<" - GreaterEqual -> ">=" - LessEqual -> "<=" - And -> "&&" - Or -> "||" - -instance Operator UnaryOperator where - precedence operator = case operator of - Negate -> 7 - Not -> 7 - - operatorStr operator = case operator of - Not -> "!" - Negate -> "-" +type Program = PProgram Annotation diff --git a/library/Batsh/Ast/Poly.hs b/library/Batsh/Ast/Poly.hs index 9fa41b5..6e49641 100644 --- a/library/Batsh/Ast/Poly.hs +++ b/library/Batsh/Ast/Poly.hs @@ -1,24 +1,24 @@ module Batsh.Ast.Poly where -data Literal a +data PLiteral a = Bool Bool a | Int Int a | Float Float a | String String a - | List [Expression a] a + | List [PExpression a] a deriving (Eq, Read, Show) -data LeftValue a +data PLeftValue a = Identifier Identifier a - | ListAccess (LeftValue a, Expression a) a + | ListAccess (PLeftValue a, PExpression a) a deriving (Eq, Read, Show) -data UnaryOperator a +data PUnaryOperator a = Not a | Negate a deriving (Eq, Read, Show) -data BinaryOperator a +data PBinaryOperator a = Plus a | Minus a | Multiply a @@ -37,32 +37,32 @@ data BinaryOperator a | Or a deriving (Eq, Read, Show) -data Expression a - = LeftValue (LeftValue a) a - | Literal (Literal a) a - | Unary (UnaryOperator a, Expression a) a - | Binary (BinaryOperator a, Expression a, Expression a) a - | Assign (LeftValue a, Expression a) a - | Call (FunctionName, [Expression a]) a +data PExpression a + = LeftValue (PLeftValue a) a + | Literal (PLiteral a) a + | Unary (PUnaryOperator a, PExpression a) a + | Binary (PBinaryOperator a, PExpression a, PExpression a) a + | Assign (PLeftValue a, PExpression a) a + | Call (FunctionName, [PExpression a]) a deriving (Eq, Read, Show) -data Statement a +data PStatement a = Comment String a - | Block [Statement a] a - | Expression (Expression a) a - | If (Expression a, Statement a) a - | IfElse (Expression a, Statement a, Statement a) a - | While (Expression a, Statement a) a + | Block [PStatement a] a + | Expression (PExpression a) a + | If (PExpression a, PStatement a) a + | IfElse (PExpression a, PStatement a, PStatement a) a + | While (PExpression a, PStatement a) a | Global Identifier a - | Return (Maybe (Expression a)) a + | Return (Maybe (PExpression a)) a deriving (Eq, Read, Show) -data TopLevel a - = Statement (Statement a) a - | Function (FunctionName, [Parameter], [Statement a]) a +data PTopLevel a + = Statement (PStatement a) a + | Function (FunctionName, [Parameter], [PStatement a]) a deriving (Eq, Read, Show) -data Program a = Program [TopLevel a] a deriving (Eq, Read, Show) +data PProgram a = Program [PTopLevel a] a deriving (Eq, Read, Show) type Identifier = String @@ -74,7 +74,7 @@ class Operator a where precedence :: a -> Int operatorStr :: a -> String -instance Operator (UnaryOperator a) where +instance Operator (PUnaryOperator a) where precedence operator = case operator of Negate _ -> 7 Not _ -> 7 @@ -83,7 +83,7 @@ instance Operator (UnaryOperator a) where Not _ -> "!" Negate _ -> "-" -instance Operator (BinaryOperator a) where +instance Operator (PBinaryOperator a) where precedence operator = case operator of Or _ -> 0 And _ -> 1 diff --git a/library/Batsh/Generator.hs b/library/Batsh/Generator.hs index 497da61..eb91ddf 100644 --- a/library/Batsh/Generator.hs +++ b/library/Batsh/Generator.hs @@ -15,25 +15,25 @@ import Batsh.Ast renderLiteral :: Literal -> Builder renderLiteral literal = case literal of - Int num -> intDec num - Float num -> floatDec num - String str -> mconcat [charUtf8 '"', - stringUtf8 str, - charUtf8 '"'] - Bool bool -> case bool of + Int num _ -> intDec num + Float num _ -> floatDec num + String str _ -> mconcat [charUtf8 '"', + stringUtf8 str, + charUtf8 '"'] + Bool bool _ -> case bool of True -> stringUtf8 "true" False -> stringUtf8 "false" - List list -> mconcat [stringUtf8 "[", - renderExpressions list, - stringUtf8 "]"] + List list _ -> mconcat [stringUtf8 "[", + renderExpressions list, + stringUtf8 "]"] renderLeftValue :: LeftValue -> Builder renderLeftValue lvalue = case lvalue of - Identifier ident -> stringUtf8 ident - ListAccess (lvalue, expr) -> mconcat [renderLeftValue lvalue, - stringUtf8 "[", - renderExpression expr, - stringUtf8 "]"] + Identifier ident _ -> stringUtf8 ident + ListAccess (lvalue, expr) _ -> mconcat [renderLeftValue lvalue, + stringUtf8 "[", + renderExpression expr, + stringUtf8 "]"] -- Render a subexpression. Add parenthesis if and only if necessary. renderSubExpression :: (Operator a) => a -> Expression -> Builder @@ -43,9 +43,11 @@ renderSubExpression operator subExpr = case subExpr of -- if subexpression is a binary expression and the precedence of operator is -- lower, then add (). E.g. + is less precedent than *. - Binary (subOperator, _, _) | precedence subOperator < precedence operator -> + Binary (subOperator, _, _) _ + | precedence subOperator < precedence operator -> renderedWithParen - Unary (subOperator, _) | precedence subOperator < precedence operator -> + Unary (subOperator, _) _ + | precedence subOperator < precedence operator -> renderedWithParen _ -> rendered @@ -64,17 +66,17 @@ renderBinary (operator, left, right) = renderExpression :: Expression -> Builder renderExpression expr = case expr of - LeftValue lvalue -> renderLeftValue lvalue - Literal literal -> renderLiteral literal - Unary unary -> renderUnary unary - Binary binary -> renderBinary binary - Assign (lvalue, expr) -> mconcat [renderLeftValue lvalue, - stringUtf8 " = ", - renderExpression expr] - Call (ident, exprs) -> mconcat [stringUtf8 ident, - charUtf8 '(', - renderExpressions exprs, - charUtf8 ')'] + LeftValue lvalue _ -> renderLeftValue lvalue + Literal literal _ -> renderLiteral literal + Unary unary _ -> renderUnary unary + Binary binary _ -> renderBinary binary + Assign (lvalue, expr) _ -> mconcat [renderLeftValue lvalue, + stringUtf8 " = ", + renderExpression expr] + Call (ident, exprs) _ -> mconcat [stringUtf8 ident, + charUtf8 '(', + renderExpressions exprs, + charUtf8 ')'] renderSeparateList :: [a] -> String -> (a -> Builder) -> Builder renderSeparateList list separator renderer = case list of @@ -108,33 +110,33 @@ renderStatementIndent stmt level isClause = mconcat [renderIndention level, renderedStmt] where renderedStmt = case stmt of - Comment comment -> + Comment comment _ -> mconcat [stringUtf8 "//", stringUtf8 comment] - Block stmts -> renderBlock stmts level - Expression expr -> withSemicolon $ renderExpression expr - If (expr, stmt) -> + Block stmts _ -> renderBlock stmts level + Expression expr _ -> withSemicolon $ renderExpression expr + If (expr, stmt) _ -> mconcat [stringUtf8 "if (", renderExpression expr, stringUtf8 ") ", renderClause stmt] - IfElse (expr, thenStmt, elseStmt) -> + IfElse (expr, thenStmt, elseStmt) _ -> mconcat [stringUtf8 "if (", renderExpression expr, stringUtf8 ") ", renderClause thenStmt, stringUtf8 " else ", renderClause elseStmt] - While (expr, stmt) -> + While (expr, stmt) _ -> mconcat [stringUtf8 "while (", renderExpression expr, stringUtf8 ") ", renderClause stmt] - Global ident -> withSemicolon $ + Global ident _ -> withSemicolon $ mconcat [stringUtf8 "global ", stringUtf8 ident] - Return (Just expr) -> withSemicolon $ + Return (Just expr) _ -> withSemicolon $ mconcat [stringUtf8 "return ", renderExpression expr] - Return Nothing -> withSemicolon $ stringUtf8 "return" + Return Nothing _ -> withSemicolon $ stringUtf8 "return" where withSemicolon builder = mconcat [builder, charUtf8 ';']; renderClause stmt = renderStatementIndent stmt level True @@ -144,8 +146,8 @@ renderStatement stmt = renderStatementIndent stmt 0 False renderTopLevel :: TopLevel -> Builder renderTopLevel toplevel = case toplevel of - Statement stmt -> renderStatement stmt - Function (name, params, stmts) -> + Statement stmt _ -> renderStatement stmt + Function (name, params, stmts) _ -> mconcat [stringUtf8 "function ", stringUtf8 name, charUtf8 '(', @@ -154,7 +156,7 @@ renderTopLevel toplevel = case toplevel of renderBlock stmts 0] renderProgram :: Program -> Builder -renderProgram (Program program) = +renderProgram (Program program _) = mconcat [renderSeparateList program "\n" renderTopLevel, charUtf8 '\n'] diff --git a/library/Batsh/Parser.y b/library/Batsh/Parser.y index 893b2ec..782a468 100644 --- a/library/Batsh/Parser.y +++ b/library/Batsh/Parser.y @@ -73,66 +73,66 @@ import qualified Batsh.Lexer as Lexer %% -program : toplevels { $1 } +program : toplevels { Ast.Program $1 () } -toplevel : statement { Ast.Statement $1 } +toplevel : statement { Ast.Statement $1 () } | function ident '(' idents ')' - '{' statements '}' { Ast.Function ($2, $4, $7)} - -statement : comment { Ast.Comment $1 } - | '{' statements '}' { Ast.Block $2 } - | expression ';' { Ast.Expression $1 } - | global ident ';' { Ast.Global $2 } - | return expression ';' { Ast.Return $ Just $2 } - | return ';' { Ast.Return $ Nothing } + '{' statements '}' { Ast.Function ($2, $4, $7) ()} + +statement : comment { Ast.Comment $1 () } + | '{' statements '}' { Ast.Block $2 () } + | expression ';' { Ast.Expression $1 () } + | global ident ';' { Ast.Global $2 () } + | return expression ';' { Ast.Return (Just $2) () } + | return ';' { Ast.Return Nothing () } | if_statement { $1 } | loop_statement { $1 } if_statement : if '(' expression ')' - statement %prec if { Ast.If ($3, $5) } + statement %prec if { Ast.If ($3, $5) () } | if '(' expression ')' - statement else statement { Ast.IfElse ($3, $5, $7) } + statement else statement { Ast.IfElse ($3, $5, $7) () } loop_statement: while '(' expression ')' - statement { Ast.While ($3, $5) } + statement { Ast.While ($3, $5) () } -expression : leftvalue { Ast.LeftValue $1 } - | literal { Ast.Literal $1 } - | ident '(' expressions ')' { Ast.Call ($1, $3) } +expression : leftvalue { Ast.LeftValue $1 () } + | literal { Ast.Literal $1 () } + | ident '(' expressions ')' { Ast.Call ($1, $3) () } | '(' expression ')' { $2 } - | unary { Ast.Unary $1 } - | binary { Ast.Binary $1 } - | leftvalue '=' expression { Ast.Assign ($1, $3) } - -unary : '!' expression { Ast.Not, $2 } - | '-' expression %prec '-' { Ast.Negate, $2 } - -binary : expression '+' expression { Ast.Plus, $1, $3 } - | expression '-' expression { Ast.Minus, $1, $3 } - | expression '*' expression { Ast.Multiply, $1, $3 } - | expression '/' expression { Ast.Divide, $1, $3 } - | expression '%' expression { Ast.Modulo, $1, $3 } - | expression '++' expression { Ast.Concat, $1, $3 } - | expression '==' expression { Ast.Equal, $1, $3 } - | expression '!=' expression { Ast.NotEqual, $1, $3 } - | expression '===' expression { Ast.ArithEqual, $1, $3 } - | expression '!==' expression { Ast.ArithNotEqual, $1, $3 } - | expression '>' expression { Ast.Greater, $1, $3 } - | expression '<' expression { Ast.Less, $1, $3 } - | expression '>=' expression { Ast.GreaterEqual, $1, $3 } - | expression '<=' expression { Ast.LessEqual, $1, $3 } - | expression '&&' expression { Ast.And, $1, $3 } - | expression '||' expression { Ast.Or, $1, $3 } - -literal : true { Ast.Bool True } - | false { Ast.Bool False } - | int { Ast.Int $1 } - | float { Ast.Float $1 } - | string { Ast.String $1 } - | '[' expressions ']' { Ast.List $2 } - -leftvalue : ident { Ast.Identifier $1 } - | leftvalue '[' expression ']' { Ast.ListAccess ($1, $3) } + | unary { Ast.Unary $1 () } + | binary { Ast.Binary $1 () } + | leftvalue '=' expression { Ast.Assign ($1, $3) () } + +unary : '!' expression { Ast.Not (), $2 } + | '-' expression %prec '-' { Ast.Negate (), $2 } + +binary : expression '+' expression { Ast.Plus (), $1, $3 } + | expression '-' expression { Ast.Minus (), $1, $3 } + | expression '*' expression { Ast.Multiply (), $1, $3 } + | expression '/' expression { Ast.Divide (), $1, $3 } + | expression '%' expression { Ast.Modulo (), $1, $3 } + | expression '++' expression { Ast.Concat (), $1, $3 } + | expression '==' expression { Ast.Equal (), $1, $3 } + | expression '!=' expression { Ast.NotEqual (), $1, $3 } + | expression '===' expression { Ast.ArithEqual (), $1, $3 } + | expression '!==' expression { Ast.ArithNotEqual (), $1, $3 } + | expression '>' expression { Ast.Greater (), $1, $3 } + | expression '<' expression { Ast.Less (), $1, $3 } + | expression '>=' expression { Ast.GreaterEqual (), $1, $3 } + | expression '<=' expression { Ast.LessEqual (), $1, $3 } + | expression '&&' expression { Ast.And (), $1, $3 } + | expression '||' expression { Ast.Or (), $1, $3 } + +literal : true { Ast.Bool True () } + | false { Ast.Bool False () } + | int { Ast.Int $1 () } + | float { Ast.Float $1 () } + | string { Ast.String $1 () } + | '[' expressions ']' { Ast.List $2 () } + +leftvalue : ident { Ast.Identifier $1 () } + | leftvalue '[' expression ']' { Ast.ListAccess ($1, $3) () } toplevels : { [] } | toplevel toplevels { $1 : $2 } @@ -153,7 +153,7 @@ parseError :: [Lexer.Token] -> a parseError _ = error "Parse error" parse :: String -> Ast.Program -parse code = Ast.Program $ program $ scanTokens code +parse code = program $ scanTokens code parseTopLevel :: String -> Ast.TopLevel parseTopLevel = toplevel . scanTokens diff --git a/library/Batsh/SymbolTable.hs b/library/Batsh/SymbolTable.hs index e6ebd21..a03a16a 100644 --- a/library/Batsh/SymbolTable.hs +++ b/library/Batsh/SymbolTable.hs @@ -45,14 +45,14 @@ lookup symbolTable scope ident = Nothing -> Nothing -- scope does not exist create :: Program -> SymbolTable -create (Program program) = +create (Program program _) = SymbolTable $ SMap.fromList $ (SGlobal, globalTable) : functionTables where (functions, topLevelStmts) = List.partition (\topl -> case topl of - Function _ -> True - Statement _ -> False + Function _ _ -> True + Statement _ _ -> False ) program; - stmts = map (\(Statement stmt) -> stmt) topLevelStmts + stmts = map (\(Statement stmt _) -> stmt) topLevelStmts -- Add function definitions to global table functionDefTable = Table (foldl addFuncDef SMap.empty functions, Nothing) -- Add global statements to global table @@ -61,7 +61,7 @@ create (Program program) = functionTables :: [(Scope, Table)] functionTables = map processFunction functions addFuncDef :: MapIdentifierSymbol -> TopLevel -> MapIdentifierSymbol - addFuncDef table (Function (func, _, _)) = + addFuncDef table (Function (func, _, _) _) = let scope = SGlobal in -- functions can be defined only in the global scope let symbol = (func, STFunction, scope) in if not (SMap.member func table) then @@ -70,7 +70,7 @@ create (Program program) = symbolTableError $ "Redefinition of function '" ++ func ++ "'" processFunction :: TopLevel -> (Scope, Table) -processFunction (Function (func, params, stmts)) = +processFunction (Function (func, params, stmts) _) = (scope, table) where scope = SFunction func; @@ -90,20 +90,20 @@ processFunction (Function (func, params, stmts)) = processStatement :: Table -> Scope -> Statement -> Table processStatement table scope stmt = case stmt of - Block stmts -> processStatements table scope stmts -- TODO block scope - Expression expr -> processExpression table scope expr - If (expr, subStmt) -> + Block stmts _ -> processStatements table scope stmts -- TODO block scope + Expression expr _ -> processExpression table scope expr + If (expr, subStmt) _ -> let exprTable = processExpression table scope expr in processStatement exprTable scope subStmt - IfElse (expr, thenStmt, elseStmt) -> + IfElse (expr, thenStmt, elseStmt) _ -> let exprTable = processExpression table scope expr in let thenTable = processStatement exprTable scope thenStmt in processStatement thenTable scope elseStmt - While (expr, subStmt) -> + While (expr, subStmt) _ -> let exprTable = processExpression table scope expr in processStatement exprTable scope subStmt - Global ident -> processIdentifier table SGlobal ident - Return (Just expr) -> processExpression table scope expr + Global ident _ -> processIdentifier table SGlobal ident + Return (Just expr) _ -> processExpression table scope expr _ -> table processStatements :: Table -> Scope -> [Statement] -> Table @@ -112,17 +112,17 @@ processStatements table scope stmts = processExpression :: Table -> Scope -> Expression -> Table processExpression table scope expr = case expr of - Assign (lvalue, subExpr) -> processLeftValue table scope lvalue - Unary (_, subExpr) -> processExpression table scope subExpr - Binary (_, left, right) -> + Assign (lvalue, subExpr) _ -> processLeftValue table scope lvalue + Unary (_, subExpr) _ -> processExpression table scope subExpr + Binary (_, left, right) _ -> let exprTable = processExpression table scope left in processExpression exprTable scope right _ -> table processLeftValue :: Table -> Scope -> LeftValue -> Table processLeftValue table scope lvalue = case lvalue of - Identifier ident -> processIdentifier table scope ident - ListAccess (lvalue, subExpr) -> + Identifier ident _ -> processIdentifier table scope ident + ListAccess (lvalue, subExpr) _ -> let lvalueTable = processLeftValue table scope lvalue in processExpression lvalueTable scope subExpr diff --git a/test/ParserTest.hs b/test/ParserTest.hs index 24dca24..78aacee 100644 --- a/test/ParserTest.hs +++ b/test/ParserTest.hs @@ -17,19 +17,9 @@ testParser = do let testStatement = testAst parseStatement let testExpression = testAst parseExpression -- Expression - testExpression "3" (Literal $ Int 3) - testExpression "[4.2 + 3, \"str\", []]" (Literal $ List [Binary (Plus, - Literal $ Float 4.2 , Literal $ Int 3), Literal $ String "str", - Literal $ List []]) - testExpression "a+2+9*4e2 > 5 || true && 4 != \"str\"" (Binary (Or, Binary ( - Greater, Binary (Plus, Binary (Plus, LeftValue (Identifier "a"), Literal ( - Int 2)), Binary (Multiply, Literal (Int 9), Literal (Float 400.0))), Literal - (Int 5)), Binary (And, Literal (Bool True), Binary (NotEqual, Literal (Int - 4), Literal (String "str"))))) + testExpression "3" (Literal (Int 3 ())()) -- Statement - testStatement "func(4);" (Expression $ Call ("func", [Literal $ Int 4])) - testStatement "if (1) if (2) {true;} else {}" (If (Literal (Int 1), IfElse ( - Literal (Int 2), Block [Expression (Literal (Bool True))], Block []))) + testStatement "func(4);" (Expression (Call ("func",[Literal (Int 4 ()) ()]) ()) ()) testCaseDir = "test/testcase" testCases = ["arith", "array", "assignment", "block", "command", "comment", diff --git a/test/testcase/Batsh/arith.ast b/test/testcase/Batsh/arith.ast index eb91c71..7517ead 100644 --- a/test/testcase/Batsh/arith.ast +++ b/test/testcase/Batsh/arith.ast @@ -1,103 +1,187 @@ Program [ Statement - (Expression (Call ( "println" , [ Literal (Bool False) ] ))) + (Expression + (Call ( "println" , [ Literal (Bool False ()) () ] ) ()) ()) + () , Statement - (Expression (Call ( "println" , [ Literal (Bool True) ] ))) + (Expression + (Call ( "println" , [ Literal (Bool True ()) () ] ) ()) ()) + () , Statement - (Expression (Call ( "println" , [ Literal (Int 42) ] ))) + (Expression + (Call ( "println" , [ Literal (Int 42 ()) () ] ) ()) ()) + () , Statement (Expression (Call ( "println" , [ Binary - ( Plus - , Literal (Int 1) + ( Plus () + , Literal (Int 1 ()) () , Binary - ( Multiply - , Binary ( Plus , Literal (Int 4) , Literal (Int 6) ) - , Literal (Int 3) + ( Multiply () + , Binary + ( Plus () , Literal (Int 4 ()) () , Literal (Int 6 ()) () ) () + , Literal (Int 3 ()) () ) + () ) + () ] - ))) + ) + ()) + ()) + () , Statement (Expression (Call ( "println" , [ Binary - ( Minus - , Literal (Int 8) - , Binary ( Modulo , Literal (Int 3) , Literal (Int 2) ) + ( Minus () + , Literal (Int 8 ()) () + , Binary + ( Modulo () , Literal (Int 3 ()) () , Literal (Int 2 ()) () ) () ) + () ] - ))) + ) + ()) + ()) + () , Statement (Expression (Call ( "println" , [ Binary - ( Minus , Unary ( Negate , Literal (Int 9) ) , Literal (Int 9) ) + ( Minus () + , Unary ( Negate () , Literal (Int 9 ()) () ) () + , Literal (Int 9 ()) () + ) + () ] - ))) + ) + ()) + ()) + () , Statement (Expression (Call ( "println" , [ Binary - ( Divide - , Binary ( Plus , Literal (Int 2) , Literal (Int 8) ) - , Literal (Int 3) + ( Divide () + , Binary + ( Plus () , Literal (Int 2 ()) () , Literal (Int 8 ()) () ) () + , Literal (Int 3 ()) () ) + () ] - ))) + ) + ()) + ()) + () , Statement (Expression (Call ( "println" - , [ Binary ( ArithEqual , Literal (Int 2) , Literal (Int 2) ) ] - ))) + , [ Binary + ( ArithEqual () , Literal (Int 2 ()) () , Literal (Int 2 ()) () ) + () + ] + ) + ()) + ()) + () , Statement (Expression (Call ( "println" - , [ Binary ( ArithNotEqual , Literal (Int 6) , Literal (Int 8) ) ] - ))) + , [ Binary + ( ArithNotEqual () + , Literal (Int 6 ()) () + , Literal (Int 8 ()) () + ) + () + ] + ) + ()) + ()) + () , Statement (Expression (Call ( "println" - , [ Binary ( Greater , Literal (Int 3) , Literal (Int 2) ) ] - ))) + , [ Binary + ( Greater () , Literal (Int 3 ()) () , Literal (Int 2 ()) () ) () + ] + ) + ()) + ()) + () , Statement (Expression (Call ( "println" - , [ Binary ( Less , Literal (Int 4) , Literal (Int 5) ) ] - ))) + , [ Binary + ( Less () , Literal (Int 4 ()) () , Literal (Int 5 ()) () ) () + ] + ) + ()) + ()) + () , Statement (Expression (Call ( "println" - , [ Binary ( GreaterEqual , Literal (Int 6) , Literal (Int 2) ) ] - ))) + , [ Binary + ( GreaterEqual () , Literal (Int 6 ()) () , Literal (Int 2 ()) () ) + () + ] + ) + ()) + ()) + () , Statement (Expression (Call ( "println" - , [ Binary ( LessEqual , Literal (Int 19) , Literal (Int 30) ) ] - ))) + , [ Binary + ( LessEqual () , Literal (Int 19 ()) () , Literal (Int 30 ()) () ) + () + ] + ) + ()) + ()) + () , Statement (Expression - (Call ( "println" , [ Unary ( Not , Literal (Bool True) ) ] ))) + (Call + ( "println" , [ Unary ( Not () , Literal (Bool True ()) () ) () ] ) + ()) + ()) + () , Statement (Expression - (Call ( "println" , [ Unary ( Not , Literal (Bool False) ) ] ))) + (Call + ( "println" + , [ Unary ( Not () , Literal (Bool False ()) () ) () ] + ) + ()) + ()) + () , Statement (Expression (Call ( "println" , [ Unary - ( Not , Binary ( Minus , Literal (Int 2) , Literal (Int 1) ) ) + ( Not () + , Binary + ( Minus () , Literal (Int 2 ()) () , Literal (Int 1 ()) () ) () + ) + () ] - ))) + ) + ()) + ()) + () ] + () diff --git a/test/testcase/Batsh/array.ast b/test/testcase/Batsh/array.ast index d2ef864..bbd6bc2 100644 --- a/test/testcase/Batsh/array.ast +++ b/test/testcase/Batsh/array.ast @@ -2,95 +2,149 @@ Program [ Statement (Expression (Assign - ( Identifier "a" + ( Identifier "a" () , Literal (List - [ Literal (String "") - , Literal (String "y") - , Unary ( Negate , Literal (Int 1) ) - , Literal (Int 1) - ]) - ))) + [ Literal (String "" ()) () + , Literal (String "y" ()) () + , Unary ( Negate () , Literal (Int 1 ()) () ) () + , Literal (Int 1 ()) () + ] + ()) + () + ) + ()) + ()) + () , Statement (Expression (Assign - ( ListAccess ( Identifier "a" , Literal (Int 0) ) - , Binary ( Multiply , Literal (Int 2) , Literal (Int 9) ) - ))) + ( ListAccess ( Identifier "a" () , Literal (Int 0 ()) () ) () + , Binary + ( Multiply () , Literal (Int 2 ()) () , Literal (Int 9 ()) () ) () + ) + ()) + ()) + () , Statement (Expression (Assign - ( ListAccess ( Identifier "a" , Literal (Int 2) ) - , Literal (String "abx") - ))) + ( ListAccess ( Identifier "a" () , Literal (Int 2 ()) () ) () + , Literal (String "abx" ()) () + ) + ()) + ()) + () , Statement (Expression (Assign - ( ListAccess ( Identifier "a" , Literal (Int 4) ) + ( ListAccess ( Identifier "a" () , Literal (Int 4 ()) () ) () , Binary - ( Concat - , Literal (String "5") - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) + ( Concat () + , Literal (String "5" ()) () + , LeftValue + (ListAccess ( Identifier "a" () , Literal (Int 0 ()) () ) ()) () ) - ))) + () + ) + ()) + ()) + () , Statement (Expression (Call ( "println" - , [ LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 1) )) - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 2) )) - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 3) )) - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 4) )) + , [ LeftValue + (ListAccess ( Identifier "a" () , Literal (Int 0 ()) () ) ()) () + , LeftValue + (ListAccess ( Identifier "a" () , Literal (Int 1 ()) () ) ()) () + , LeftValue + (ListAccess ( Identifier "a" () , Literal (Int 2 ()) () ) ()) () + , LeftValue + (ListAccess ( Identifier "a" () , Literal (Int 3 ()) () ) ()) () + , LeftValue + (ListAccess ( Identifier "a" () , Literal (Int 4 ()) () ) ()) () ] - ))) + ) + ()) + ()) + () , Statement (Expression (Assign - ( Identifier "a" + ( Identifier "a" () , Literal - (List [ Literal (Int 1) , Literal (Int 2) , Literal (Int 3) ]) - ))) + (List + [ Literal (Int 1 ()) () + , Literal (Int 2 ()) () + , Literal (Int 3 ()) () + ] + ()) + () + ) + ()) + ()) + () , Statement (Expression (Call ( "println" - , [ LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 1) )) - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 2) )) + , [ LeftValue + (ListAccess ( Identifier "a" () , Literal (Int 0 ()) () ) ()) () + , LeftValue + (ListAccess ( Identifier "a" () , Literal (Int 1 ()) () ) ()) () + , LeftValue + (ListAccess ( Identifier "a" () , Literal (Int 2 ()) () ) ()) () ] - ))) + ) + ()) + ()) + () , Statement (Expression (Call ( "println" , [ Binary - ( Multiply + ( Multiply () , Binary - ( Concat - , Literal (String "10") - , LeftValue (ListAccess ( Identifier "a" , Literal (Int 0) )) + ( Concat () + , Literal (String "10" ()) () + , LeftValue + (ListAccess ( Identifier "a" () , Literal (Int 0 ()) () ) ()) () ) - , Literal (Int 2) + () + , Literal (Int 2 ()) () ) + () ] - ))) + ) + ()) + ()) + () , Statement (Expression (Call ( "println" - , [ Call ( "len" , [ LeftValue (Identifier "a") ] ) ] - ))) + , [ Call ( "len" , [ LeftValue (Identifier "a" ()) () ] ) () ] + ) + ()) + ()) + () , Statement (Expression (Call ( "println" , [ Binary - ( Multiply - , Call ( "len" , [ LeftValue (Identifier "a") ] ) - , Literal (Int 8) + ( Multiply () + , Call ( "len" , [ LeftValue (Identifier "a" ()) () ] ) () + , Literal (Int 8 ()) () ) + () ] - ))) - , Statement (Comment "println([1, 2, 3]);") + ) + ()) + ()) + () + , Statement (Comment "println([1, 2, 3]);" ()) () ] + () diff --git a/test/testcase/Batsh/assignment.ast b/test/testcase/Batsh/assignment.ast index a310fc0..3e22254 100644 --- a/test/testcase/Batsh/assignment.ast +++ b/test/testcase/Batsh/assignment.ast @@ -2,46 +2,73 @@ Program [ Statement (Expression (Assign - ( Identifier "a" + ( Identifier "a" () , Binary - ( Concat - , Literal (String "Value: ") + ( Concat () + , Literal (String "Value: " ()) () , Binary - ( Plus - , Literal (Int 1) + ( Plus () + , Literal (Int 1 ()) () , Binary - ( Multiply - , Binary ( Plus , Literal (Int 4) , Literal (Int 6) ) - , Literal (Int 3) + ( Multiply () + , Binary + ( Plus () , Literal (Int 4 ()) () , Literal (Int 6 ()) () ) () + , Literal (Int 3 ()) () ) + () ) + () ) - ))) + () + ) + ()) + ()) + () , Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "a") ] ))) + (Expression + (Call ( "println" , [ LeftValue (Identifier "a" ()) () ] ) ()) ()) + () , Statement (Expression (Assign - ( Identifier "b" - , Binary ( Plus , Literal (Int 3) , Literal (Int 4) ) - ))) + ( Identifier "b" () + , Binary + ( Plus () , Literal (Int 3 ()) () , Literal (Int 4 ()) () ) () + ) + ()) + ()) + () , Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "b") ] ))) + (Expression + (Call ( "println" , [ LeftValue (Identifier "b" ()) () ] ) ()) ()) + () , Statement (Expression - (Assign ( Identifier "c" , LeftValue (Identifier "a") ))) + (Assign + ( Identifier "c" () , LeftValue (Identifier "a" ()) () ) ()) + ()) + () , Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "c") ] ))) + (Expression + (Call ( "println" , [ LeftValue (Identifier "c" ()) () ] ) ()) ()) + () , Statement (Expression (Assign - ( Identifier "d" + ( Identifier "d" () , Binary - ( Concat - , LeftValue (Identifier "b") - , LeftValue (Identifier "c") + ( Concat () + , LeftValue (Identifier "b" ()) () + , LeftValue (Identifier "c" ()) () ) - ))) + () + ) + ()) + ()) + () , Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "d") ] ))) + (Expression + (Call ( "println" , [ LeftValue (Identifier "d" ()) () ] ) ()) ()) + () ] + () diff --git a/test/testcase/Batsh/block.ast b/test/testcase/Batsh/block.ast index 7ea6d30..08bfa2a 100644 --- a/test/testcase/Batsh/block.ast +++ b/test/testcase/Batsh/block.ast @@ -1,20 +1,30 @@ Program - [ Statement (Comment "Level 0 Start") + [ Statement (Comment "Level 0 Start" ()) () , Statement - (Expression (Call ( "println" , [ Literal (String "Hello") ] ))) + (Expression + (Call ( "println" , [ Literal (String "Hello" ()) () ] ) ()) ()) + () , Statement (Block - [ Comment "Level 1 Start" - , Expression (Call ( "println" , [ Literal (String "Lo") ] )) + [ Comment "Level 1 Start" () + , Expression + (Call ( "println" , [ Literal (String "Lo" ()) () ] ) ()) () , Block - [ Comment "Level 2 Start" + [ Comment "Level 2 Start" () , Expression - (Call ( "println" , [ Literal (String "and behold") ] )) - , Comment "Level 2 End" + (Call ( "println" , [ Literal (String "and behold" ()) () ] ) ()) + () + , Comment "Level 2 End" () ] - , Comment "Level 1 End" - ]) + () + , Comment "Level 1 End" () + ] + ()) + () , Statement - (Expression (Call ( "println" , [ Literal (String "End") ] ))) - , Statement (Comment "Level 0 End") + (Expression + (Call ( "println" , [ Literal (String "End" ()) () ] ) ()) ()) + () + , Statement (Comment "Level 0 End" ()) () ] + () diff --git a/test/testcase/Batsh/command.ast b/test/testcase/Batsh/command.ast index 9c014a9..7c714aa 100644 --- a/test/testcase/Batsh/command.ast +++ b/test/testcase/Batsh/command.ast @@ -3,29 +3,51 @@ Program (Expression (Call ( "call" - , [ Literal (String "println") - , Literal (String "Println Called") + , [ Literal (String "println" ()) () + , Literal (String "Println Called" ()) () ] - ))) + ) + ()) + ()) + () , Statement (Expression (Assign - ( Identifier "cmd" - , Binary ( Concat , Literal (String "ec") , Literal (String "ho") ) - ))) + ( Identifier "cmd" () + , Binary + ( Concat () + , Literal (String "ec" ()) () + , Literal (String "ho" ()) () + ) + () + ) + ()) + ()) + () , Statement (Expression (Call ( "call" - , [ LeftValue (Identifier "cmd") , Literal (String "Echo Called") ] - ))) + , [ LeftValue (Identifier "cmd" ()) () + , Literal (String "Echo Called" ()) () + ] + ) + ()) + ()) + () , Statement (Expression (Assign - ( Identifier "retval" - , Call ( "echo" , [ Literal (String "Value 100%") ] ) - ))) + ( Identifier "retval" () + , Call ( "echo" , [ Literal (String "Value 100%" ()) () ] ) () + ) + ()) + ()) + () , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "retval") ] ))) + (Call ( "println" , [ LeftValue (Identifier "retval" ()) () ] ) ()) + ()) + () ] + () diff --git a/test/testcase/Batsh/comment.ast b/test/testcase/Batsh/comment.ast index c7718f8..1defe64 100644 --- a/test/testcase/Batsh/comment.ast +++ b/test/testcase/Batsh/comment.ast @@ -1,16 +1,28 @@ Program [ Statement - (Expression (Assign ( Identifier "a" , Literal (Int 3) ))) - , Statement (Comment " This is comment 1") + (Expression + (Assign ( Identifier "a" () , Literal (Int 3 ()) () ) ()) ()) + () + , Statement (Comment " This is comment 1" ()) () , Statement (Expression (Assign - ( Identifier "a" + ( Identifier "a" () , Binary - ( Multiply , LeftValue (Identifier "a") , Literal (Int 5) ) - ))) - , Statement (Comment " This is comment 2") + ( Multiply () + , LeftValue (Identifier "a" ()) () + , Literal (Int 5 ()) () + ) + () + ) + ()) + ()) + () + , Statement (Comment " This is comment 2" ()) () , Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "a") ] ))) - , Statement (Comment "This is comment 3") + (Expression + (Call ( "println" , [ LeftValue (Identifier "a" ()) () ] ) ()) ()) + () + , Statement (Comment "This is comment 3" ()) () ] + () diff --git a/test/testcase/Batsh/exists.ast b/test/testcase/Batsh/exists.ast index 2d2664c..881c9ac 100644 --- a/test/testcase/Batsh/exists.ast +++ b/test/testcase/Batsh/exists.ast @@ -2,27 +2,47 @@ Program [ Statement (Expression (Assign - ( Identifier "ex" - , Call ( "exists" , [ Literal (String "Makefile") ] ) - ))) + ( Identifier "ex" () + , Call ( "exists" , [ Literal (String "Makefile" ()) () ] ) () + ) + ()) + ()) + () , Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "ex") ] ))) + (Expression + (Call ( "println" , [ LeftValue (Identifier "ex" ()) () ] ) ()) ()) + () , Statement - (Expression (Call ( "exists" , [ Literal (String "Makefile") ] ))) + (Expression + (Call ( "exists" , [ Literal (String "Makefile" ()) () ] ) ()) ()) + () , Statement (If - ( Call ( "exists" , [ Literal (String "Makefile") ] ) + ( Call ( "exists" , [ Literal (String "Makefile" ()) () ] ) () , Block - [ Expression (Call ( "println" , [ Literal (String "Yes") ] )) ] - )) + [ Expression + (Call ( "println" , [ Literal (String "Yes" ()) () ] ) ()) () + ] + () + ) + ()) + () , Statement (IfElse - ( Call ( "exists" , [ Literal (String "none") ] ) + ( Call ( "exists" , [ Literal (String "none" ()) () ] ) () , Block [ Expression - (Call ( "println" , [ Literal (String "Impossible") ] )) + (Call ( "println" , [ Literal (String "Impossible" ()) () ] ) ()) + () ] + () , Block - [ Expression (Call ( "println" , [ Literal (String "No") ] )) ] - )) + [ Expression + (Call ( "println" , [ Literal (String "No" ()) () ] ) ()) () + ] + () + ) + ()) + () ] + () diff --git a/test/testcase/Batsh/function.ast b/test/testcase/Batsh/function.ast index 47c3434..bf98a6d 100644 --- a/test/testcase/Batsh/function.ast +++ b/test/testcase/Batsh/function.ast @@ -1,96 +1,159 @@ Program - [ Statement (Comment " Function call") + [ Statement (Comment " Function call" ()) () , Function ( "func1" , [ "p1" , "p2" ] , [ Expression (Call ( "println" - , [ LeftValue (Identifier "p1") , LeftValue (Identifier "p2") ] - )) + , [ LeftValue (Identifier "p1" ()) () + , LeftValue (Identifier "p2" ()) () + ] + ) + ()) + () ] ) + () , Statement (Expression (Call ( "func1" - , [ Literal (String "Hello") , Literal (String "World") ] - ))) - , Statement (Comment " Global and local variables") + , [ Literal (String "Hello" ()) () + , Literal (String "World" ()) () + ] + ) + ()) + ()) + () + , Statement (Comment " Global and local variables" ()) () , Statement (Expression - (Assign ( Identifier "v1" , Literal (String "Global V1") ))) + (Assign + ( Identifier "v1" () , Literal (String "Global V1" ()) () ) ()) + ()) + () , Statement (Expression - (Assign ( Identifier "v2" , Literal (String "Global V2") ))) + (Assign + ( Identifier "v2" () , Literal (String "Global V2" ()) () ) ()) + ()) + () , Statement (Expression - (Assign ( Identifier "v3" , Literal (String "Global V3") ))) + (Assign + ( Identifier "v3" () , Literal (String "Global V3" ()) () ) ()) + ()) + () , Function ( "func2" , [ "p" ] , [ Expression (Assign - ( Identifier "v1" + ( Identifier "v1" () , Binary - ( Concat , Literal (String "Local ") , LeftValue (Identifier "p") ) - )) - , Expression (Call ( "println" , [ LeftValue (Identifier "v1") ] )) - , Expression (Call ( "println" , [ LeftValue (Identifier "v2") ] )) - , Global "v3" - , Global "v4" + ( Concat () + , Literal (String "Local " ()) () + , LeftValue (Identifier "p" ()) () + ) + () + ) + ()) + () + , Expression + (Call ( "println" , [ LeftValue (Identifier "v1" ()) () ] ) ()) () + , Expression + (Call ( "println" , [ LeftValue (Identifier "v2" ()) () ] ) ()) () + , Global "v3" () + , Global "v4" () , Expression - (Assign ( Identifier "v3" , Literal (String "V3 Modified.") )) + (Assign + ( Identifier "v3" () , Literal (String "V3 Modified." ()) () ) ()) + () ] ) + () , Statement - (Expression (Call ( "func2" , [ Literal (String "Var") ] ))) + (Expression + (Call ( "func2" , [ Literal (String "Var" ()) () ] ) ()) ()) + () , Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "v1") ] ))) + (Expression + (Call ( "println" , [ LeftValue (Identifier "v1" ()) () ] ) ()) ()) + () , Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "v3") ] ))) - , Statement (Comment " Return value") + (Expression + (Call ( "println" , [ LeftValue (Identifier "v3" ()) () ] ) ()) ()) + () + , Statement (Comment " Return value" ()) () , Function ( "func3" , [ "num" ] , [ Return (Just (Binary - ( Plus , LeftValue (Identifier "num") , Literal (Int 41) ))) + ( Plus () + , LeftValue (Identifier "num" ()) () + , Literal (Int 41 ()) () + ) + ())) + () ] ) - , Statement (Expression (Call ( "func3" , [ Literal (Int 4) ] ))) - , Statement (Expression (Call ( "println" , [] ))) + () + , Statement + (Expression (Call ( "func3" , [ Literal (Int 4 ()) () ] ) ()) ()) + () + , Statement (Expression (Call ( "println" , [] ) ()) ()) () , Statement (Expression (Assign - ( Identifier "ret" , Call ( "func3" , [ Literal (Int 1) ] ) ))) + ( Identifier "ret" () + , Call ( "func3" , [ Literal (Int 1 ()) () ] ) () + ) + ()) + ()) + () , Statement (Expression (Call ( "println" - , [ Literal (String "Returned:") , LeftValue (Identifier "ret") ] - ))) - , Statement (Comment " Argument containing space") + , [ Literal (String "Returned:" ()) () + , LeftValue (Identifier "ret" ()) () + ] + ) + ()) + ()) + () + , Statement (Comment " Argument containing space" ()) () , Function ( "g" , [ "text" ] - , [ Return (Just (LeftValue (Identifier "text"))) ] + , [ Return (Just (LeftValue (Identifier "text" ()) ())) () ] ) + () , Function ( "f" , [ "text" ] , [ Return - (Just (Call ( "g" , [ LeftValue (Identifier "text") ] ))) + (Just (Call ( "g" , [ LeftValue (Identifier "text" ()) () ] ) ())) + () ] ) + () , Statement (Expression (Assign - ( Identifier "test" - , Call ( "f" , [ Literal (String "Param with space") ] ) - ))) + ( Identifier "test" () + , Call ( "f" , [ Literal (String "Param with space" ()) () ] ) () + ) + ()) + ()) + () , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "test") ] ))) + (Call ( "println" , [ LeftValue (Identifier "test" ()) () ] ) ()) + ()) + () ] + () diff --git a/test/testcase/Batsh/if.ast b/test/testcase/Batsh/if.ast index 7452d32..a99e50f 100644 --- a/test/testcase/Batsh/if.ast +++ b/test/testcase/Batsh/if.ast @@ -1,77 +1,136 @@ Program [ Statement (If - ( Binary ( Less , Literal (Int 2) , Literal (Int 10) ) + ( Binary + ( Less () , Literal (Int 2 ()) () , Literal (Int 10 ()) () ) () , Block - [ Expression (Call ( "println" , [ Literal (String "Yes") ] )) ] - )) + [ Expression + (Call ( "println" , [ Literal (String "Yes" ()) () ] ) ()) () + ] + () + ) + ()) + () , Statement (IfElse - ( Literal (Bool True) + ( Literal (Bool True ()) () , Block [ IfElse - ( Literal (Bool False) + ( Literal (Bool False ()) () , Block [ Expression (Assign - ( Identifier "v" - , Binary ( Plus , Literal (Int 4) , Literal (Int 1) ) - )) + ( Identifier "v" () + , Binary + ( Plus () , Literal (Int 4 ()) () , Literal (Int 1 ()) () ) () + ) + ()) + () ] + () , Block - [ Expression (Assign ( Identifier "v" , Literal (Int 2) )) ] + [ Expression + (Assign ( Identifier "v" () , Literal (Int 2 ()) () ) ()) () + ] + () ) + () , If - ( Literal (Bool False) - , Expression (Call ( "println" , [ Literal (String "no") ] )) + ( Literal (Bool False ()) () + , Expression + (Call ( "println" , [ Literal (String "no" ()) () ] ) ()) () ) + () ] - , Block [] - )) + () + , Block [] () + ) + ()) + () , Statement - (Expression (Call ( "println" , [ LeftValue (Identifier "v") ] ))) + (Expression + (Call ( "println" , [ LeftValue (Identifier "v" ()) () ] ) ()) ()) + () , Statement (If - ( Binary ( Greater , Literal (Int 2) , Literal (Int 1) ) - , Expression (Call ( "println" , [ Literal (String "True") ] )) - )) + ( Binary + ( Greater () , Literal (Int 2 ()) () , Literal (Int 1 ()) () ) () + , Expression + (Call ( "println" , [ Literal (String "True" ()) () ] ) ()) () + ) + ()) + () , Statement (If - ( Binary ( ArithEqual , Literal (Int 1) , Literal (Int 12) ) + ( Binary + ( ArithEqual () , Literal (Int 1 ()) () , Literal (Int 12 ()) () ) + () , Block - [ Expression (Call ( "println" , [ Literal (String "No") ] )) ] - )) + [ Expression + (Call ( "println" , [ Literal (String "No" ()) () ] ) ()) () + ] + () + ) + ()) + () , Statement (IfElse - ( Binary ( Equal , Literal (String "a") , Literal (String "b") ) + ( Binary + ( Equal () + , Literal (String "a" ()) () + , Literal (String "b" ()) () + ) + () , Block - [ Expression (Call ( "println" , [ Literal (String "No") ] )) ] + [ Expression + (Call ( "println" , [ Literal (String "No" ()) () ] ) ()) () + ] + () , Block [ Expression - (Call ( "println" , [ Literal (String "a is not b") ] )) + (Call ( "println" , [ Literal (String "a is not b" ()) () ] ) ()) + () ] - )) + () + ) + ()) + () , Statement - (Expression (Assign ( Identifier "num" , Literal (Int 43) ))) + (Expression + (Assign ( Identifier "num" () , Literal (Int 43 ()) () ) ()) ()) + () , Statement (If ( Binary - ( Equal , Literal (String "43") , LeftValue (Identifier "num") ) + ( Equal () + , Literal (String "43" ()) () + , LeftValue (Identifier "num" ()) () + ) + () , Block [ Expression - (Call ( "println" , [ Literal (String "43 == num") ] )) + (Call ( "println" , [ Literal (String "43 == num" ()) () ] ) ()) () ] - )) + () + ) + ()) + () , Statement (If ( Binary - ( ArithEqual - , Literal (String "43") - , LeftValue (Identifier "num") + ( ArithEqual () + , Literal (String "43" ()) () + , LeftValue (Identifier "num" ()) () ) + () , Block [ Expression - (Call ( "println" , [ Literal (String "43 === num") ] )) + (Call ( "println" , [ Literal (String "43 === num" ()) () ] ) ()) + () ] - )) + () + ) + ()) + () ] + () diff --git a/test/testcase/Batsh/recursion.ast b/test/testcase/Batsh/recursion.ast index 80f4444..c77c291 100644 --- a/test/testcase/Batsh/recursion.ast +++ b/test/testcase/Batsh/recursion.ast @@ -1,105 +1,183 @@ Program - [ Statement (Comment " Loop") + [ Statement (Comment " Loop" ()) () , Function ( "loop" , [ "num" ] , [ Expression - (Call ( "println" , [ LeftValue (Identifier "num") ] )) + (Call ( "println" , [ LeftValue (Identifier "num" ()) () ] ) ()) () , If ( Binary - ( Greater , LeftValue (Identifier "num") , Literal (Int 0) ) + ( Greater () + , LeftValue (Identifier "num" ()) () + , Literal (Int 0 ()) () + ) + () , Block [ Expression (Call ( "loop" , [ Binary - ( Minus , LeftValue (Identifier "num") , Literal (Int 1) ) + ( Minus () + , LeftValue (Identifier "num" ()) () + , Literal (Int 1 ()) () + ) + () ] - )) + ) + ()) + () ] + () ) + () ] ) - , Statement (Expression (Call ( "loop" , [ Literal (Int 10) ] ))) - , Statement (Comment " Factorial") + () + , Statement + (Expression (Call ( "loop" , [ Literal (Int 10 ()) () ] ) ()) ()) + () + , Statement (Comment " Factorial" ()) () , Function ( "fact" , [ "num" ] , [ IfElse ( Binary - ( ArithEqual , LeftValue (Identifier "num") , Literal (Int 0) ) - , Block [ Return (Just (Literal (Int 1))) ] + ( ArithEqual () + , LeftValue (Identifier "num" ()) () + , Literal (Int 0 ()) () + ) + () + , Block [ Return (Just (Literal (Int 1 ()) ())) () ] () , Block [ Return (Just (Binary - ( Multiply + ( Multiply () , Call ( "fact" , [ Binary - ( Minus , LeftValue (Identifier "num") , Literal (Int 1) ) + ( Minus () + , LeftValue (Identifier "num" ()) () + , Literal (Int 1 ()) () + ) + () ] ) - , LeftValue (Identifier "num") - ))) + () + , LeftValue (Identifier "num" ()) () + ) + ())) + () ] + () ) + () ] ) + () , Statement (Expression - (Call ( "println" , [ Call ( "fact" , [ Literal (Int 5) ] ) ] ))) - , Statement (Comment " Fibonacci") + (Call + ( "println" , [ Call ( "fact" , [ Literal (Int 5 ()) () ] ) () ] ) + ()) + ()) + () + , Statement (Comment " Fibonacci" ()) () , Function ( "fibonacci" , [ "num" ] , [ IfElse ( Binary - ( ArithEqual , LeftValue (Identifier "num") , Literal (Int 0) ) - , Block [ Return (Just (Literal (Int 0))) ] + ( ArithEqual () + , LeftValue (Identifier "num" ()) () + , Literal (Int 0 ()) () + ) + () + , Block [ Return (Just (Literal (Int 0 ()) ())) () ] () , IfElse ( Binary - ( ArithEqual , LeftValue (Identifier "num") , Literal (Int 1) ) - , Block [ Return (Just (Literal (Int 1))) ] + ( ArithEqual () + , LeftValue (Identifier "num" ()) () + , Literal (Int 1 ()) () + ) + () + , Block [ Return (Just (Literal (Int 1 ()) ())) () ] () , Block [ Return (Just (Binary - ( Plus + ( Plus () , Call ( "fibonacci" , [ Binary - ( Minus , LeftValue (Identifier "num") , Literal (Int 2) ) + ( Minus () + , LeftValue (Identifier "num" ()) () + , Literal (Int 2 ()) () + ) + () ] ) + () , Call ( "fibonacci" , [ Binary - ( Minus , LeftValue (Identifier "num") , Literal (Int 1) ) + ( Minus () + , LeftValue (Identifier "num" ()) () + , Literal (Int 1 ()) () + ) + () ] ) - ))) + () + ) + ())) + () ] + () ) + () ) + () ] ) + () , Statement - (Expression (Assign ( Identifier "i" , Literal (Int 0) ))) + (Expression + (Assign ( Identifier "i" () , Literal (Int 0 ()) () ) ()) ()) + () , Statement (While - ( Binary ( Less , LeftValue (Identifier "i") , Literal (Int 7) ) + ( Binary + ( Less () + , LeftValue (Identifier "i" ()) () + , Literal (Int 7 ()) () + ) + () , Block [ Expression (Call ( "println" - , [ Call ( "fibonacci" , [ LeftValue (Identifier "i") ] ) ] - )) + , [ Call ( "fibonacci" , [ LeftValue (Identifier "i" ()) () ] ) () + ] + ) + ()) + () , Expression (Assign - ( Identifier "i" - , Binary ( Plus , LeftValue (Identifier "i") , Literal (Int 1) ) - )) + ( Identifier "i" () + , Binary + ( Plus () + , LeftValue (Identifier "i" ()) () + , Literal (Int 1 ()) () + ) + () + ) + ()) + () ] - )) + () + ) + ()) + () ] + () diff --git a/test/testcase/Batsh/string.ast b/test/testcase/Batsh/string.ast index 60876fd..7f53a88 100644 --- a/test/testcase/Batsh/string.ast +++ b/test/testcase/Batsh/string.ast @@ -1,84 +1,138 @@ Program [ Statement - (Expression (Call ( "println" , [ Literal (String "BYVoid") ] ))) + (Expression + (Call ( "println" , [ Literal (String "BYVoid" ()) () ] ) ()) ()) + () , Statement - (Expression (Call ( "println" , [ Literal (String "Slash/") ] ))) + (Expression + (Call ( "println" , [ Literal (String "Slash/" ()) () ] ) ()) ()) + () , Statement (Expression - (Call ( "println" , [ Literal (String "Backslash\\\\") ] ))) + (Call + ( "println" , [ Literal (String "Backslash\\\\" ()) () ] ) ()) + ()) + () , Statement (Expression - (Call ( "println" , [ Literal (String "Quote\\\"'") ] ))) + (Call ( "println" , [ Literal (String "Quote\\\"'" ()) () ] ) ()) + ()) + () , Statement (Expression - (Call ( "println" , [ Literal (String "Tab\\tTab") ] ))) - , Statement (Comment "println(\"Newline\\nLine2\");") - , Statement (Comment "println(\"!\");") + (Call ( "println" , [ Literal (String "Tab\\tTab" ()) () ] ) ()) + ()) + () + , Statement (Comment "println(\"Newline\\nLine2\");" ()) () + , Statement (Comment "println(\"!\");" ()) () , Statement (Expression (Call ( "println" , [ Binary - ( Concat + ( Concat () , Binary - ( Concat + ( Concat () , Binary - ( Concat , Literal (String "http://") , Literal (String "www.") ) - , Literal (String "byvoid") + ( Concat () + , Literal (String "http://" ()) () + , Literal (String "www." ()) () + ) + () + , Literal (String "byvoid" ()) () ) - , Literal (String ".com") + () + , Literal (String ".com" ()) () ) + () ] - ))) + ) + ()) + ()) + () , Statement (Expression (Call ( "println" , [ Binary - ( Concat + ( Concat () , Binary - ( Concat - , Binary ( Divide , Literal (Int 6) , Literal (Int 2) ) - , Literal (String "BYVoid") + ( Concat () + , Binary + ( Divide () , Literal (Int 6 ()) () , Literal (Int 2 ()) () ) () + , Literal (String "BYVoid" ()) () ) - , Binary ( Plus , Literal (Int 3) , Literal (Int 5) ) + () + , Binary + ( Plus () , Literal (Int 3 ()) () , Literal (Int 5 ()) () ) () ) + () ] - ))) + ) + ()) + ()) + () , Statement (Expression (Call ( "println" - , [ Binary ( Plus , Literal (Int 3) , Literal (String "3") ) ] - ))) + , [ Binary + ( Plus () , Literal (Int 3 ()) () , Literal (String "3" ()) () ) () + ] + ) + ()) + ()) + () , Statement (Expression (Call ( "println" , [ Binary - ( Concat - , Binary ( Plus , Literal (Int 3) , Literal (String "3") ) - , Literal (String "2") + ( Concat () + , Binary + ( Plus () , Literal (Int 3 ()) () , Literal (String "3" ()) () ) () + , Literal (String "2" ()) () ) + () ] - ))) + ) + ()) + ()) + () , Statement (Expression (Call ( "println" , [ Binary - ( Plus - , Literal (Int 3) - , Binary ( Concat , Literal (String "3") , Literal (String "2") ) + ( Plus () + , Literal (Int 3 ()) () + , Binary + ( Concat () + , Literal (String "3" ()) () + , Literal (String "2" ()) () + ) + () ) + () ] - ))) + ) + ()) + ()) + () , Statement (Expression (Call ( "println" , [ Binary - ( Equal , Literal (String "BYVoid") , Literal (String "BYVoid") ) + ( Equal () + , Literal (String "BYVoid" ()) () + , Literal (String "BYVoid" ()) () + ) + () ] - ))) + ) + ()) + ()) + () ] + () diff --git a/test/testcase/Batsh/while.ast b/test/testcase/Batsh/while.ast index 86791f0..4a90311 100644 --- a/test/testcase/Batsh/while.ast +++ b/test/testcase/Batsh/while.ast @@ -1,52 +1,108 @@ Program [ Statement - (Expression (Assign ( Identifier "i" , Literal (Int 0) ))) + (Expression + (Assign ( Identifier "i" () , Literal (Int 0 ()) () ) ()) ()) + () , Statement (While - ( Binary ( Less , LeftValue (Identifier "i") , Literal (Int 5) ) + ( Binary + ( Less () + , LeftValue (Identifier "i" ()) () + , Literal (Int 5 ()) () + ) + () , Block [ Expression (Call ( "print" , [ Binary - ( Concat , LeftValue (Identifier "i") , Literal (String " ") ) + ( Concat () + , LeftValue (Identifier "i" ()) () + , Literal (String " " ()) () + ) + () ] - )) + ) + ()) + () , Expression (Assign - ( Identifier "i" - , Binary ( Plus , LeftValue (Identifier "i") , Literal (Int 1) ) - )) + ( Identifier "i" () + , Binary + ( Plus () + , LeftValue (Identifier "i" ()) () + , Literal (Int 1 ()) () + ) + () + ) + ()) + () ] - )) - , Statement (Expression (Call ( "println" , [] ))) - , Statement (Comment " Fibonacci") + () + ) + ()) + () + , Statement (Expression (Call ( "println" , [] ) ()) ()) () + , Statement (Comment " Fibonacci" ()) () , Statement - (Expression (Assign ( Identifier "n" , Literal (Int 0) ))) + (Expression + (Assign ( Identifier "n" () , Literal (Int 0 ()) () ) ()) ()) + () , Statement - (Expression (Assign ( Identifier "i" , Literal (Int 0) ))) + (Expression + (Assign ( Identifier "i" () , Literal (Int 0 ()) () ) ()) ()) + () , Statement - (Expression (Assign ( Identifier "j" , Literal (Int 1) ))) + (Expression + (Assign ( Identifier "j" () , Literal (Int 1 ()) () ) ()) ()) + () , Statement (While - ( Binary ( Less , LeftValue (Identifier "n") , Literal (Int 40) ) + ( Binary + ( Less () + , LeftValue (Identifier "n" ()) () + , Literal (Int 40 ()) () + ) + () , Block [ Expression (Assign - ( Identifier "k" + ( Identifier "k" () , Binary - ( Plus , LeftValue (Identifier "i") , LeftValue (Identifier "j") ) - )) + ( Plus () + , LeftValue (Identifier "i" ()) () + , LeftValue (Identifier "j" ()) () + ) + () + ) + ()) + () , Expression - (Assign ( Identifier "i" , LeftValue (Identifier "j") )) + (Assign + ( Identifier "i" () , LeftValue (Identifier "j" ()) () ) ()) + () , Expression - (Assign ( Identifier "j" , LeftValue (Identifier "k") )) + (Assign + ( Identifier "j" () , LeftValue (Identifier "k" ()) () ) ()) + () , Expression (Assign - ( Identifier "n" - , Binary ( Plus , LeftValue (Identifier "n") , Literal (Int 1) ) - )) - , Expression (Call ( "println" , [ LeftValue (Identifier "k") ] )) + ( Identifier "n" () + , Binary + ( Plus () + , LeftValue (Identifier "n" ()) () + , Literal (Int 1 ()) () + ) + () + ) + ()) + () + , Expression + (Call ( "println" , [ LeftValue (Identifier "k" ()) () ] ) ()) () ] - )) + () + ) + ()) + () ] + () From 4a5855e01f609a744fed0bfaed5276554b522114 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Wed, 5 Nov 2014 22:27:06 +0100 Subject: [PATCH 40/53] Add position annotation to Ast --- library/Batsh/Ast.hs | 18 +- library/Batsh/Ast/Poly.hs | 69 ++++ library/Batsh/Lexer.x | 20 +- library/Batsh/Parser.y | 260 ++++++++----- test/ParserTest.hs | 11 +- test/testcase/Batsh/arith.ast | 482 +++++++++++++++++++---- test/testcase/Batsh/array.ast | 471 ++++++++++++++++++---- test/testcase/Batsh/assignment.ast | 211 ++++++++-- test/testcase/Batsh/block.ast | 107 ++++- test/testcase/Batsh/command.ast | 119 ++++-- test/testcase/Batsh/comment.ast | 81 +++- test/testcase/Batsh/exists.ast | 152 ++++++-- test/testcase/Batsh/function.ast | 501 ++++++++++++++++++++---- test/testcase/Batsh/if.ast | 484 +++++++++++++++++++---- test/testcase/Batsh/recursion.ast | 602 ++++++++++++++++++++++++----- test/testcase/Batsh/string.ast | 395 +++++++++++++++---- test/testcase/Batsh/while.ast | 307 ++++++++++++--- 17 files changed, 3543 insertions(+), 747 deletions(-) diff --git a/library/Batsh/Ast.hs b/library/Batsh/Ast.hs index 563aa17..917e485 100644 --- a/library/Batsh/Ast.hs +++ b/library/Batsh/Ast.hs @@ -3,20 +3,20 @@ module Batsh.Ast(module Poly, module Batsh.Ast) where import Batsh.Ast.Poly as Poly import Batsh.Lexer(LexPos) -type Annotation = () +type AstAnnotation = LexPos -type Literal = PLiteral Annotation +type Literal = PLiteral AstAnnotation -type LeftValue = PLeftValue Annotation +type LeftValue = PLeftValue AstAnnotation -type UnaryOperator = PUnaryOperator Annotation +type UnaryOperator = PUnaryOperator AstAnnotation -type BinaryOperator = PBinaryOperator Annotation +type BinaryOperator = PBinaryOperator AstAnnotation -type Expression = PExpression Annotation +type Expression = PExpression AstAnnotation -type Statement = PStatement Annotation +type Statement = PStatement AstAnnotation -type TopLevel = PTopLevel Annotation +type TopLevel = PTopLevel AstAnnotation -type Program = PProgram Annotation +type Program = PProgram AstAnnotation diff --git a/library/Batsh/Ast/Poly.hs b/library/Batsh/Ast/Poly.hs index 6e49641..998def0 100644 --- a/library/Batsh/Ast/Poly.hs +++ b/library/Batsh/Ast/Poly.hs @@ -70,6 +70,75 @@ type FunctionName = Identifier type Parameter = Identifier +class AstNode a where + annot :: a annot -> annot + +instance AstNode PLiteral where + annot node = case node of + Bool _ annot -> annot + Int _ annot -> annot + Float _ annot -> annot + String _ annot -> annot + List _ annot -> annot + +instance AstNode PLeftValue where + annot node = case node of + Identifier _ annot -> annot + ListAccess _ annot -> annot + +instance AstNode PUnaryOperator where + annot node = case node of + Not annot -> annot + Negate annot -> annot + +instance AstNode PBinaryOperator where + annot node = case node of + Plus annot -> annot + Minus annot -> annot + Multiply annot -> annot + Divide annot -> annot + Modulo annot -> annot + Concat annot -> annot + Equal annot -> annot + NotEqual annot -> annot + ArithEqual annot -> annot + ArithNotEqual annot -> annot + Greater annot -> annot + Less annot -> annot + GreaterEqual annot -> annot + LessEqual annot -> annot + And annot -> annot + Or annot -> annot + +instance AstNode PExpression where + annot node = case node of + LeftValue _ annot -> annot + Literal _ annot -> annot + Unary _ annot -> annot + Binary _ annot -> annot + Assign _ annot -> annot + Call _ annot -> annot + +instance AstNode PStatement where + annot node = case node of + Comment _ annot -> annot + Block _ annot -> annot + Expression _ annot -> annot + If _ annot -> annot + IfElse _ annot -> annot + While _ annot -> annot + Global _ annot -> annot + Return _ annot -> annot + +instance AstNode PTopLevel where + annot node = case node of + Statement _ annot -> annot + Function _ annot -> annot + +instance AstNode PProgram where + annot node = case node of + Program _ annot -> annot + class Operator a where precedence :: a -> Int operatorStr :: a -> String diff --git a/library/Batsh/Lexer.x b/library/Batsh/Lexer.x index 119ac16..e919cda 100644 --- a/library/Batsh/Lexer.x +++ b/library/Batsh/Lexer.x @@ -41,7 +41,7 @@ $charesc = [abfnrtv\\\"\'\&] @string_in = . # [\"\\] | " " | @escape | @gap @string = \" @string_in* \" -haskell :- +tokens :- $white+ { skip } @decimal { makeReadableLexeme Int } @hexadecimal{ makeReadableLexeme Int } @@ -129,21 +129,21 @@ data Token | LEOF deriving (Eq, Read, Show) -data LexPos = LexPos - { lexPosStartByte :: Int, - lexPosLine :: Int, - lexPosColumn :: Int, - lexLength :: Int } +data LexPos = LP + { lpLine :: Int, + lpColumn :: Int, + lpStartByte :: Int, + lpLength :: Int } deriving (Eq, Read, Show) data Lexeme = Lex LexPos Token deriving (Eq, Read, Show) makeLexPos :: AlexPosn -> Int -> LexPos makeLexPos (AlexPn startByte line column) length = - LexPos {lexPosStartByte = startByte, - lexPosLine = line, - lexPosColumn = column, - lexLength = length} + LP {lpStartByte = startByte, + lpLength = length, + lpLine = line, + lpColumn = column} getMatchedString :: AlexInput -> Int -> String getMatchedString (_, _, _, str) len = take len str diff --git a/library/Batsh/Parser.y b/library/Batsh/Parser.y index 782a468..81ec5cf 100644 --- a/library/Batsh/Parser.y +++ b/library/Batsh/Parser.y @@ -8,6 +8,7 @@ module Batsh.Parser(parse, import qualified Batsh.Ast as Ast import qualified Batsh.Lexer as Lexer +import Prelude hiding(span) } -- parse function terminal name @@ -16,49 +17,49 @@ import qualified Batsh.Lexer as Lexer %name statement statement %name expression expression -%tokentype { Lexer.Token } +%tokentype { Lexer.Lexeme } %error { parseError } %token - int { Lexer.Int $$ } - float { Lexer.Float $$ } - string { Lexer.String $$ } - true { Lexer.TTrue } - false { Lexer.TFalse } - if { Lexer.If } - else { Lexer.Else } - while { Lexer.While } - function { Lexer.Function } - global { Lexer.Global } - return { Lexer.Return } - '!' { Lexer.Not } - ';' { Lexer.Semicolon } - ',' { Lexer.Comma } - '+' { Lexer.Plus } - '-' { Lexer.Minus } - '*' { Lexer.Multiply } - '/' { Lexer.Divide } - '%' { Lexer.Modulo } - '++' { Lexer.Concat } - '=' { Lexer.Assign } - '==' { Lexer.Equal } - '!=' { Lexer.NotEqual } - '===' { Lexer.ArithEqual } - '!==' { Lexer.ArithNotEqual } - '>' { Lexer.Greater } - '<' { Lexer.Less } - '>=' { Lexer.GreaterEqual } - '<=' { Lexer.LessEqual } - '&&' { Lexer.And } - '||' { Lexer.Or } - '(' { Lexer.LParen } - ')' { Lexer.RParen } - '[' { Lexer.LBrack } - ']' { Lexer.RBrack } - '{' { Lexer.LBrace } - '}' { Lexer.RBrace } - comment { Lexer.Comment $$ } - ident { Lexer.Identifier $$ } + int { Lexer.Lex _ (Lexer.Int _) } + float { Lexer.Lex _ (Lexer.Float _) } + string { Lexer.Lex _ (Lexer.String _) } + true { Lexer.Lex _ Lexer.TTrue } + false { Lexer.Lex _ Lexer.TFalse } + if { Lexer.Lex _ Lexer.If } + else { Lexer.Lex _ Lexer.Else } + while { Lexer.Lex _ Lexer.While } + function { Lexer.Lex _ Lexer.Function } + global { Lexer.Lex _ Lexer.Global } + return { Lexer.Lex _ Lexer.Return } + '!' { Lexer.Lex _ Lexer.Not } + ';' { Lexer.Lex _ Lexer.Semicolon } + ',' { Lexer.Lex _ Lexer.Comma } + '+' { Lexer.Lex _ Lexer.Plus } + '-' { Lexer.Lex _ Lexer.Minus } + '*' { Lexer.Lex _ Lexer.Multiply } + '/' { Lexer.Lex _ Lexer.Divide } + '%' { Lexer.Lex _ Lexer.Modulo } + '++' { Lexer.Lex _ Lexer.Concat } + '=' { Lexer.Lex _ Lexer.Assign } + '==' { Lexer.Lex _ Lexer.Equal } + '!=' { Lexer.Lex _ Lexer.NotEqual } + '===' { Lexer.Lex _ Lexer.ArithEqual } + '!==' { Lexer.Lex _ Lexer.ArithNotEqual } + '>' { Lexer.Lex _ Lexer.Greater } + '<' { Lexer.Lex _ Lexer.Less } + '>=' { Lexer.Lex _ Lexer.GreaterEqual } + '<=' { Lexer.Lex _ Lexer.LessEqual } + '&&' { Lexer.Lex _ Lexer.And } + '||' { Lexer.Lex _ Lexer.Or } + '(' { Lexer.Lex _ Lexer.LParen } + ')' { Lexer.Lex _ Lexer.RParen } + '[' { Lexer.Lex _ Lexer.LBrack } + ']' { Lexer.Lex _ Lexer.RBrack } + '{' { Lexer.Lex _ Lexer.LBrace } + '}' { Lexer.Lex _ Lexer.RBrace } + comment { Lexer.Lex _ (Lexer.Comment _) } + ident { Lexer.Lex _ (Lexer.Identifier _) } %right if else %right '=' @@ -73,66 +74,100 @@ import qualified Batsh.Lexer as Lexer %% -program : toplevels { Ast.Program $1 () } +program : toplevels { Ast.Program $1 $ + span (apos $ head $1) (apos $ last $1) } -toplevel : statement { Ast.Statement $1 () } +toplevel : statement { Ast.Statement $1 (apos $1) } | function ident '(' idents ')' - '{' statements '}' { Ast.Function ($2, $4, $7) ()} - -statement : comment { Ast.Comment $1 () } - | '{' statements '}' { Ast.Block $2 () } - | expression ';' { Ast.Expression $1 () } - | global ident ';' { Ast.Global $2 () } - | return expression ';' { Ast.Return (Just $2) () } - | return ';' { Ast.Return Nothing () } + '{' statements '}' { Ast.Function (exStr $2, $4, $7) + $ span (pos $1) (pos $8)} + +statement : comment { Ast.Comment (exStr $1) + $ pos $1 } + | '{' statements '}' { Ast.Block $2 + $ span (pos $1) (pos $3) } + | expression ';' { Ast.Expression $1 + $ span (apos $1) (pos $2) } + | global ident ';' { Ast.Global (exStr $2) + $ span (pos $1) (pos $3) } + | return expression ';' { Ast.Return (Just $2) + $ span (pos $1) (pos $3) } + | return ';' { Ast.Return Nothing + $ span (pos $1) (pos $2) } | if_statement { $1 } | loop_statement { $1 } if_statement : if '(' expression ')' - statement %prec if { Ast.If ($3, $5) () } + statement %prec if { Ast.If ($3, $5) + $ span (pos $1) (apos $5) } | if '(' expression ')' - statement else statement { Ast.IfElse ($3, $5, $7) () } + statement else statement { Ast.IfElse ($3, $5, $7) + $ span (pos $1) (apos $7) } loop_statement: while '(' expression ')' - statement { Ast.While ($3, $5) () } + statement { Ast.While ($3, $5) + $ span (pos $1) (apos $5) } -expression : leftvalue { Ast.LeftValue $1 () } - | literal { Ast.Literal $1 () } - | ident '(' expressions ')' { Ast.Call ($1, $3) () } +expression : leftvalue { Ast.LeftValue $1 (apos $1) } + | literal { Ast.Literal $1 (apos $1) } + | ident '(' expressions ')' { Ast.Call (exStr $1, $3) + $ span (pos $1) (pos $4) } | '(' expression ')' { $2 } - | unary { Ast.Unary $1 () } - | binary { Ast.Binary $1 () } - | leftvalue '=' expression { Ast.Assign ($1, $3) () } - -unary : '!' expression { Ast.Not (), $2 } - | '-' expression %prec '-' { Ast.Negate (), $2 } - -binary : expression '+' expression { Ast.Plus (), $1, $3 } - | expression '-' expression { Ast.Minus (), $1, $3 } - | expression '*' expression { Ast.Multiply (), $1, $3 } - | expression '/' expression { Ast.Divide (), $1, $3 } - | expression '%' expression { Ast.Modulo (), $1, $3 } - | expression '++' expression { Ast.Concat (), $1, $3 } - | expression '==' expression { Ast.Equal (), $1, $3 } - | expression '!=' expression { Ast.NotEqual (), $1, $3 } - | expression '===' expression { Ast.ArithEqual (), $1, $3 } - | expression '!==' expression { Ast.ArithNotEqual (), $1, $3 } - | expression '>' expression { Ast.Greater (), $1, $3 } - | expression '<' expression { Ast.Less (), $1, $3 } - | expression '>=' expression { Ast.GreaterEqual (), $1, $3 } - | expression '<=' expression { Ast.LessEqual (), $1, $3 } - | expression '&&' expression { Ast.And (), $1, $3 } - | expression '||' expression { Ast.Or (), $1, $3 } - -literal : true { Ast.Bool True () } - | false { Ast.Bool False () } - | int { Ast.Int $1 () } - | float { Ast.Float $1 () } - | string { Ast.String $1 () } - | '[' expressions ']' { Ast.List $2 () } - -leftvalue : ident { Ast.Identifier $1 () } - | leftvalue '[' expression ']' { Ast.ListAccess ($1, $3) () } + | unary { let (unary, pos) = $1 in + Ast.Unary unary pos } + | binary { let (binary, pos) = $1 in + Ast.Binary binary pos } + | leftvalue '=' expression { Ast.Assign ($1, $3) + $ span (apos $1) (apos $3) } + +unary : '!' expression { (Ast.Not (pos $1), $2), + span (pos $1) (apos $2) } + | '-' expression %prec '-' { (Ast.Negate (pos $1), $2), + span (pos $1) (apos $2) } + +binary : expression '+' expression { (Ast.Plus (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '-' expression { (Ast.Minus (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '*' expression { (Ast.Multiply (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '/' expression { (Ast.Divide (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '%' expression { (Ast.Modulo (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '++' expression { (Ast.Concat (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '==' expression { (Ast.Equal (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '!=' expression { (Ast.NotEqual (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '===' expression { (Ast.ArithEqual (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '!==' expression { (Ast.ArithNotEqual (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '>' expression { (Ast.Greater (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '<' expression { (Ast.Less (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '>=' expression { (Ast.GreaterEqual (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '<=' expression { (Ast.LessEqual (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '&&' expression { (Ast.And (pos $2), $1, $3), + span (apos $1) (apos $3) } + | expression '||' expression { (Ast.Or (pos $2), $1, $3), + span (apos $1) (apos $3) } + +literal : true { Ast.Bool True (pos $1) } + | false { Ast.Bool False (pos $1) } + | int { Ast.Int (exInt $1) (pos $1) } + | float { Ast.Float (exFlt $1) (pos $1) } + | string { Ast.String (exStr $1) (pos $1) } + | '[' expressions ']' { Ast.List $2 (pos $1) } + +leftvalue : ident { Ast.Identifier (exStr $1) (pos $1) } + | leftvalue '[' expression ']' { Ast.ListAccess ($1, $3) + $ span (apos $1) (pos $4) } toplevels : { [] } | toplevel toplevels { $1 : $2 } @@ -145,24 +180,57 @@ expressions : { [] } | expression ',' expressions { $1 : $3 } idents : { [] } - | ident { [$1] } - | ident ',' idents { $1 : $3 } + | ident { [exStr $1] } + | ident ',' idents { (exStr $1) : $3 } { -parseError :: [Lexer.Token] -> a +-- Get the position information of a Lexeme +pos :: Lexer.Lexeme -> Lexer.LexPos +pos (Lexer.Lex pos _) = pos + +-- Get the position information of a AstNode +apos :: Ast.AstNode a => a Lexer.LexPos -> Lexer.LexPos +apos node = Ast.annot node + +-- Merge two positions from leftmost to rightmost +span :: Lexer.LexPos -> Lexer.LexPos -> Lexer.LexPos +span left right = + Lexer.LP + { Lexer.lpStartByte = start, + Lexer.lpLength = length, + Lexer.lpLine = Lexer.lpLine left, + Lexer.lpColumn = Lexer.lpColumn left} + where + length = end - start + start = Lexer.lpStartByte left + end = Lexer.lpStartByte right + Lexer.lpLength right + +-- Extract internal data of the Lexeme +exInt :: Lexer.Lexeme -> Int +exInt (Lexer.Lex _ (Lexer.Int num)) = num + +exFlt :: Lexer.Lexeme -> Float +exFlt (Lexer.Lex _ (Lexer.Float num)) = num + +exStr :: Lexer.Lexeme -> String +exStr (Lexer.Lex _ (Lexer.Identifier str)) = str +exStr (Lexer.Lex _ (Lexer.Comment str)) = str +exStr (Lexer.Lex _ (Lexer.String str)) = str + +parseError :: [Lexer.Lexeme] -> a parseError _ = error "Parse error" parse :: String -> Ast.Program -parse code = program $ scanTokens code +parse code = program $ Lexer.scanLexemes code parseTopLevel :: String -> Ast.TopLevel -parseTopLevel = toplevel . scanTokens +parseTopLevel = toplevel . Lexer.scanLexemes parseStatement :: String -> Ast.Statement -parseStatement = statement . scanTokens +parseStatement = statement . Lexer.scanLexemes parseExpression :: String -> Ast.Expression -parseExpression = expression . scanTokens +parseExpression = expression . Lexer.scanLexemes -- TODO add pos information to AST scanTokens code = map stripPos (Lexer.scanLexemes code) diff --git a/test/ParserTest.hs b/test/ParserTest.hs index 78aacee..0abe7d6 100644 --- a/test/ParserTest.hs +++ b/test/ParserTest.hs @@ -2,6 +2,7 @@ module ParserTest where import qualified Batsh import Batsh.Ast +import Batsh.Lexer(lpLine, lpColumn, lpStartByte, lpLength, LexPos(LP)) import Batsh.Parser import Control.Monad import Test.HUnit @@ -17,9 +18,15 @@ testParser = do let testStatement = testAst parseStatement let testExpression = testAst parseExpression -- Expression - testExpression "3" (Literal (Int 3 ())()) + testExpression "3" $ Literal (Int 3 (LP {lpLine = 1, lpColumn = 1, + lpStartByte = 0, lpLength = 1})) (LP {lpLine = 1, lpColumn = 1, + lpStartByte = 0, lpLength = 1}) -- Statement - testStatement "func(4);" (Expression (Call ("func",[Literal (Int 4 ()) ()]) ()) ()) + testStatement "func(4);" $ Expression (Call ("func",[Literal (Int 4 ( + LP {lpLine = 1, lpColumn = 6, lpStartByte = 5, lpLength = 1})) (LP { + lpLine = 1, lpColumn = 6, lpStartByte = 5, lpLength = 1})]) (LP { + lpLine = 1, lpColumn = 1, lpStartByte = 0, lpLength = 7})) (LP { + lpLine = 1, lpColumn = 1, lpStartByte = 0, lpLength = 8}) testCaseDir = "test/testcase" testCases = ["arith", "array", "assignment", "block", "command", "comment", diff --git a/test/testcase/Batsh/arith.ast b/test/testcase/Batsh/arith.ast index 7517ead..33513d1 100644 --- a/test/testcase/Batsh/arith.ast +++ b/test/testcase/Batsh/arith.ast @@ -1,187 +1,505 @@ Program [ Statement (Expression - (Call ( "println" , [ Literal (Bool False ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ Literal + (Bool + False + LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 5 }) + LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 5 } + ] + ) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 14 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 } , Statement (Expression - (Call ( "println" , [ Literal (Bool True ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ Literal + (Bool + True + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 24 , lpLength = 4 }) + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 24 , lpLength = 4 } + ] + ) + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 13 }) + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 14 }) + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 14 } , Statement (Expression - (Call ( "println" , [ Literal (Int 42 ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ Literal + (Int + 42 + LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 39 , lpLength = 2 }) + LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 39 , lpLength = 2 } + ] + ) + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 31 , lpLength = 11 }) + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 31 , lpLength = 12 }) + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 31 , lpLength = 12 } , Statement (Expression (Call ( "println" , [ Binary - ( Plus () - , Literal (Int 1 ()) () + ( Plus + LP { lpLine = 4 , lpColumn = 11 , lpStartByte = 54 , lpLength = 1 } + , Literal + (Int + 1 + LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 52 , lpLength = 1 }) + LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 52 , lpLength = 1 } , Binary - ( Multiply () + ( Multiply + LP { lpLine = 4 , lpColumn = 21 , lpStartByte = 64 , lpLength = 1 } , Binary - ( Plus () , Literal (Int 4 ()) () , Literal (Int 6 ()) () ) () - , Literal (Int 3 ()) () + ( Plus + LP { lpLine = 4 , lpColumn = 16 , lpStartByte = 59 , lpLength = 1 } + , Literal + (Int + 4 + LP + { lpLine = 4 , lpColumn = 14 , lpStartByte = 57 , lpLength = 1 }) + LP { lpLine = 4 , lpColumn = 14 , lpStartByte = 57 , lpLength = 1 } + , Literal + (Int + 6 + LP + { lpLine = 4 , lpColumn = 18 , lpStartByte = 61 , lpLength = 1 }) + LP { lpLine = 4 , lpColumn = 18 , lpStartByte = 61 , lpLength = 1 } + ) + LP { lpLine = 4 , lpColumn = 14 , lpStartByte = 57 , lpLength = 5 } + , Literal + (Int + 3 + LP + { lpLine = 4 , lpColumn = 23 , lpStartByte = 66 , lpLength = 1 }) + LP { lpLine = 4 , lpColumn = 23 , lpStartByte = 66 , lpLength = 1 } ) - () + LP + { lpLine = 4 , lpColumn = 14 , lpStartByte = 57 , lpLength = 10 } ) - () + LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 52 , lpLength = 15 } ] ) - ()) - ()) - () + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 44 , lpLength = 24 }) + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 44 , lpLength = 25 }) + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 44 , lpLength = 25 } , Statement (Expression (Call ( "println" , [ Binary - ( Minus () - , Literal (Int 8 ()) () + ( Minus + LP { lpLine = 5 , lpColumn = 11 , lpStartByte = 80 , lpLength = 1 } + , Literal + (Int + 8 + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 1 }) + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 1 } , Binary - ( Modulo () , Literal (Int 3 ()) () , Literal (Int 2 ()) () ) () + ( Modulo + LP { lpLine = 5 , lpColumn = 15 , lpStartByte = 84 , lpLength = 1 } + , Literal + (Int + 3 + LP + { lpLine = 5 , lpColumn = 13 , lpStartByte = 82 , lpLength = 1 }) + LP { lpLine = 5 , lpColumn = 13 , lpStartByte = 82 , lpLength = 1 } + , Literal + (Int + 2 + LP + { lpLine = 5 , lpColumn = 17 , lpStartByte = 86 , lpLength = 1 }) + LP { lpLine = 5 , lpColumn = 17 , lpStartByte = 86 , lpLength = 1 } + ) + LP { lpLine = 5 , lpColumn = 13 , lpStartByte = 82 , lpLength = 5 } ) - () + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 9 } ] ) - ()) - ()) - () + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 18 }) + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 19 }) + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 19 } , Statement (Expression (Call ( "println" , [ Binary - ( Minus () - , Unary ( Negate () , Literal (Int 9 ()) () ) () - , Literal (Int 9 ()) () + ( Minus + LP + { lpLine = 6 , lpColumn = 12 , lpStartByte = 101 , lpLength = 1 } + , Unary + ( Negate + LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 98 , lpLength = 1 } + , Literal + (Int + 9 + LP + { lpLine = 6 , lpColumn = 10 , lpStartByte = 99 , lpLength = 1 }) + LP { lpLine = 6 , lpColumn = 10 , lpStartByte = 99 , lpLength = 1 } + ) + LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 98 , lpLength = 2 } + , Literal + (Int + 9 + LP + { lpLine = 6 , lpColumn = 14 , lpStartByte = 103 , lpLength = 1 }) + LP + { lpLine = 6 , lpColumn = 14 , lpStartByte = 103 , lpLength = 1 } ) - () + LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 98 , lpLength = 6 } ] ) - ()) - ()) - () + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 90 , lpLength = 15 }) + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 90 , lpLength = 16 }) + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 90 , lpLength = 16 } , Statement (Expression (Call ( "println" , [ Binary - ( Divide () + ( Divide + LP + { lpLine = 7 , lpColumn = 17 , lpStartByte = 123 , lpLength = 1 } , Binary - ( Plus () , Literal (Int 2 ()) () , Literal (Int 8 ()) () ) () - , Literal (Int 3 ()) () + ( Plus + LP + { lpLine = 7 , lpColumn = 12 , lpStartByte = 118 , lpLength = 1 } + , Literal + (Int + 2 + LP + { lpLine = 7 , lpColumn = 10 , lpStartByte = 116 , lpLength = 1 }) + LP + { lpLine = 7 , lpColumn = 10 , lpStartByte = 116 , lpLength = 1 } + , Literal + (Int + 8 + LP + { lpLine = 7 , lpColumn = 14 , lpStartByte = 120 , lpLength = 1 }) + LP + { lpLine = 7 , lpColumn = 14 , lpStartByte = 120 , lpLength = 1 } + ) + LP + { lpLine = 7 , lpColumn = 10 , lpStartByte = 116 , lpLength = 5 } + , Literal + (Int + 3 + LP + { lpLine = 7 , lpColumn = 19 , lpStartByte = 125 , lpLength = 1 }) + LP + { lpLine = 7 , lpColumn = 19 , lpStartByte = 125 , lpLength = 1 } ) - () + LP + { lpLine = 7 , lpColumn = 10 , lpStartByte = 116 , lpLength = 10 } ] ) - ()) - ()) - () + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 107 , lpLength = 20 }) + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 107 , lpLength = 21 }) + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 107 , lpLength = 21 } , Statement (Expression (Call ( "println" , [ Binary - ( ArithEqual () , Literal (Int 2 ()) () , Literal (Int 2 ()) () ) - () + ( ArithEqual + LP + { lpLine = 8 , lpColumn = 11 , lpStartByte = 139 , lpLength = 3 } + , Literal + (Int + 2 + LP + { lpLine = 8 , lpColumn = 9 , lpStartByte = 137 , lpLength = 1 }) + LP { lpLine = 8 , lpColumn = 9 , lpStartByte = 137 , lpLength = 1 } + , Literal + (Int + 2 + LP + { lpLine = 8 , lpColumn = 15 , lpStartByte = 143 , lpLength = 1 }) + LP + { lpLine = 8 , lpColumn = 15 , lpStartByte = 143 , lpLength = 1 } + ) + LP { lpLine = 8 , lpColumn = 9 , lpStartByte = 137 , lpLength = 7 } ] ) - ()) - ()) - () + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 129 , lpLength = 16 }) + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 129 , lpLength = 17 }) + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 129 , lpLength = 17 } , Statement (Expression (Call ( "println" , [ Binary - ( ArithNotEqual () - , Literal (Int 6 ()) () - , Literal (Int 8 ()) () + ( ArithNotEqual + LP + { lpLine = 9 , lpColumn = 11 , lpStartByte = 157 , lpLength = 3 } + , Literal + (Int + 6 + LP + { lpLine = 9 , lpColumn = 9 , lpStartByte = 155 , lpLength = 1 }) + LP { lpLine = 9 , lpColumn = 9 , lpStartByte = 155 , lpLength = 1 } + , Literal + (Int + 8 + LP + { lpLine = 9 , lpColumn = 15 , lpStartByte = 161 , lpLength = 1 }) + LP + { lpLine = 9 , lpColumn = 15 , lpStartByte = 161 , lpLength = 1 } ) - () + LP { lpLine = 9 , lpColumn = 9 , lpStartByte = 155 , lpLength = 7 } ] ) - ()) - ()) - () + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 147 , lpLength = 16 }) + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 147 , lpLength = 17 }) + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 147 , lpLength = 17 } , Statement (Expression (Call ( "println" , [ Binary - ( Greater () , Literal (Int 3 ()) () , Literal (Int 2 ()) () ) () + ( Greater + LP + { lpLine = 10 , lpColumn = 11 , lpStartByte = 175 , lpLength = 1 } + , Literal + (Int + 3 + LP + { lpLine = 10 , lpColumn = 9 , lpStartByte = 173 , lpLength = 1 }) + LP + { lpLine = 10 , lpColumn = 9 , lpStartByte = 173 , lpLength = 1 } + , Literal + (Int + 2 + LP + { lpLine = 10 , lpColumn = 13 , lpStartByte = 177 , lpLength = 1 }) + LP + { lpLine = 10 , lpColumn = 13 , lpStartByte = 177 , lpLength = 1 } + ) + LP + { lpLine = 10 , lpColumn = 9 , lpStartByte = 173 , lpLength = 5 } ] ) - ()) - ()) - () + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 165 , lpLength = 14 }) + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 165 , lpLength = 15 }) + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 165 , lpLength = 15 } , Statement (Expression (Call ( "println" , [ Binary - ( Less () , Literal (Int 4 ()) () , Literal (Int 5 ()) () ) () + ( Less + LP + { lpLine = 11 , lpColumn = 11 , lpStartByte = 191 , lpLength = 1 } + , Literal + (Int + 4 + LP + { lpLine = 11 , lpColumn = 9 , lpStartByte = 189 , lpLength = 1 }) + LP + { lpLine = 11 , lpColumn = 9 , lpStartByte = 189 , lpLength = 1 } + , Literal + (Int + 5 + LP + { lpLine = 11 , lpColumn = 13 , lpStartByte = 193 , lpLength = 1 }) + LP + { lpLine = 11 , lpColumn = 13 , lpStartByte = 193 , lpLength = 1 } + ) + LP + { lpLine = 11 , lpColumn = 9 , lpStartByte = 189 , lpLength = 5 } ] ) - ()) - ()) - () + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 181 , lpLength = 14 }) + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 181 , lpLength = 15 }) + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 181 , lpLength = 15 } , Statement (Expression (Call ( "println" , [ Binary - ( GreaterEqual () , Literal (Int 6 ()) () , Literal (Int 2 ()) () ) - () + ( GreaterEqual + LP + { lpLine = 12 , lpColumn = 11 , lpStartByte = 207 , lpLength = 2 } + , Literal + (Int + 6 + LP + { lpLine = 12 , lpColumn = 9 , lpStartByte = 205 , lpLength = 1 }) + LP + { lpLine = 12 , lpColumn = 9 , lpStartByte = 205 , lpLength = 1 } + , Literal + (Int + 2 + LP + { lpLine = 12 , lpColumn = 14 , lpStartByte = 210 , lpLength = 1 }) + LP + { lpLine = 12 , lpColumn = 14 , lpStartByte = 210 , lpLength = 1 } + ) + LP + { lpLine = 12 , lpColumn = 9 , lpStartByte = 205 , lpLength = 6 } ] ) - ()) - ()) - () + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 197 , lpLength = 15 }) + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 197 , lpLength = 16 }) + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 197 , lpLength = 16 } , Statement (Expression (Call ( "println" , [ Binary - ( LessEqual () , Literal (Int 19 ()) () , Literal (Int 30 ()) () ) - () + ( LessEqual + LP + { lpLine = 13 , lpColumn = 12 , lpStartByte = 225 , lpLength = 2 } + , Literal + (Int + 19 + LP + { lpLine = 13 , lpColumn = 9 , lpStartByte = 222 , lpLength = 2 }) + LP + { lpLine = 13 , lpColumn = 9 , lpStartByte = 222 , lpLength = 2 } + , Literal + (Int + 30 + LP + { lpLine = 13 , lpColumn = 15 , lpStartByte = 228 , lpLength = 2 }) + LP + { lpLine = 13 , lpColumn = 15 , lpStartByte = 228 , lpLength = 2 } + ) + LP + { lpLine = 13 , lpColumn = 9 , lpStartByte = 222 , lpLength = 8 } ] ) - ()) - ()) - () + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 214 , lpLength = 17 }) + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 214 , lpLength = 18 }) + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 214 , lpLength = 18 } , Statement (Expression (Call - ( "println" , [ Unary ( Not () , Literal (Bool True ()) () ) () ] ) - ()) - ()) - () + ( "println" + , [ Unary + ( Not + LP + { lpLine = 14 , lpColumn = 9 , lpStartByte = 241 , lpLength = 1 } + , Literal + (Bool + True + LP + { lpLine = 14 , lpColumn = 10 , lpStartByte = 242 , lpLength = 4 }) + LP + { lpLine = 14 , lpColumn = 10 , lpStartByte = 242 , lpLength = 4 } + ) + LP + { lpLine = 14 , lpColumn = 9 , lpStartByte = 241 , lpLength = 5 } + ] + ) + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 233 , lpLength = 14 }) + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 233 , lpLength = 15 }) + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 233 , lpLength = 15 } , Statement (Expression (Call ( "println" - , [ Unary ( Not () , Literal (Bool False ()) () ) () ] + , [ Unary + ( Not + LP + { lpLine = 15 , lpColumn = 9 , lpStartByte = 257 , lpLength = 1 } + , Literal + (Bool + False + LP + { lpLine = 15 , lpColumn = 10 , lpStartByte = 258 , lpLength = 5 }) + LP + { lpLine = 15 , lpColumn = 10 , lpStartByte = 258 , lpLength = 5 } + ) + LP + { lpLine = 15 , lpColumn = 9 , lpStartByte = 257 , lpLength = 6 } + ] ) - ()) - ()) - () + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 249 , lpLength = 15 }) + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 249 , lpLength = 16 }) + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 249 , lpLength = 16 } , Statement (Expression (Call ( "println" , [ Unary - ( Not () + ( Not + LP + { lpLine = 16 , lpColumn = 9 , lpStartByte = 274 , lpLength = 1 } , Binary - ( Minus () , Literal (Int 2 ()) () , Literal (Int 1 ()) () ) () + ( Minus + LP + { lpLine = 16 , lpColumn = 13 , lpStartByte = 278 , lpLength = 1 } + , Literal + (Int + 2 + LP + { lpLine = 16 , lpColumn = 11 , lpStartByte = 276 , lpLength = 1 }) + LP + { lpLine = 16 , lpColumn = 11 , lpStartByte = 276 , lpLength = 1 } + , Literal + (Int + 1 + LP + { lpLine = 16 , lpColumn = 15 , lpStartByte = 280 , lpLength = 1 }) + LP + { lpLine = 16 , lpColumn = 15 , lpStartByte = 280 , lpLength = 1 } + ) + LP + { lpLine = 16 , lpColumn = 11 , lpStartByte = 276 , lpLength = 5 } ) - () + LP + { lpLine = 16 , lpColumn = 9 , lpStartByte = 274 , lpLength = 7 } ] ) - ()) - ()) - () + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 266 , lpLength = 17 }) + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 266 , lpLength = 18 }) + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 266 , lpLength = 18 } ] - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 284 } diff --git a/test/testcase/Batsh/array.ast b/test/testcase/Batsh/array.ast index bbd6bc2..b3ce07c 100644 --- a/test/testcase/Batsh/array.ast +++ b/test/testcase/Batsh/array.ast @@ -2,149 +2,472 @@ Program [ Statement (Expression (Assign - ( Identifier "a" () + ( Identifier + "a" + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } , Literal (List - [ Literal (String "" ()) () - , Literal (String "y" ()) () - , Unary ( Negate () , Literal (Int 1 ()) () ) () - , Literal (Int 1 ()) () + [ Literal + (String + "" + LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 2 }) + LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 2 } + , Literal + (String + "y" + LP { lpLine = 1 , lpColumn = 10 , lpStartByte = 9 , lpLength = 3 }) + LP { lpLine = 1 , lpColumn = 10 , lpStartByte = 9 , lpLength = 3 } + , Unary + ( Negate + LP { lpLine = 1 , lpColumn = 15 , lpStartByte = 14 , lpLength = 1 } + , Literal + (Int + 1 + LP + { lpLine = 1 , lpColumn = 16 , lpStartByte = 15 , lpLength = 1 }) + LP { lpLine = 1 , lpColumn = 16 , lpStartByte = 15 , lpLength = 1 } + ) + LP { lpLine = 1 , lpColumn = 15 , lpStartByte = 14 , lpLength = 2 } + , Literal + (Int + 1 + LP + { lpLine = 1 , lpColumn = 19 , lpStartByte = 18 , lpLength = 1 }) + LP { lpLine = 1 , lpColumn = 19 , lpStartByte = 18 , lpLength = 1 } ] - ()) - () + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 }) + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } ) - ()) - ()) - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 5 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 21 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 21 } , Statement (Expression (Assign - ( ListAccess ( Identifier "a" () , Literal (Int 0 ()) () ) () + ( ListAccess + ( Identifier + "a" + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 1 } + , Literal + (Int + 0 + LP { lpLine = 2 , lpColumn = 3 , lpStartByte = 24 , lpLength = 1 }) + LP { lpLine = 2 , lpColumn = 3 , lpStartByte = 24 , lpLength = 1 } + ) + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 4 } , Binary - ( Multiply () , Literal (Int 2 ()) () , Literal (Int 9 ()) () ) () + ( Multiply + LP { lpLine = 2 , lpColumn = 10 , lpStartByte = 31 , lpLength = 1 } + , Literal + (Int + 2 + LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 29 , lpLength = 1 }) + LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 29 , lpLength = 1 } + , Literal + (Int + 9 + LP + { lpLine = 2 , lpColumn = 12 , lpStartByte = 33 , lpLength = 1 }) + LP { lpLine = 2 , lpColumn = 12 , lpStartByte = 33 , lpLength = 1 } + ) + LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 29 , lpLength = 5 } ) - ()) - ()) - () + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 12 }) + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 13 }) + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 13 } , Statement (Expression (Assign - ( ListAccess ( Identifier "a" () , Literal (Int 2 ()) () ) () - , Literal (String "abx" ()) () + ( ListAccess + ( Identifier + "a" + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 1 } + , Literal + (Int + 2 + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 38 , lpLength = 1 }) + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 38 , lpLength = 1 } + ) + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 4 } + , Literal + (String + "abx" + LP { lpLine = 3 , lpColumn = 8 , lpStartByte = 43 , lpLength = 5 }) + LP { lpLine = 3 , lpColumn = 8 , lpStartByte = 43 , lpLength = 5 } ) - ()) - ()) - () + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 12 }) + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 13 }) + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 13 } , Statement (Expression (Assign - ( ListAccess ( Identifier "a" () , Literal (Int 4 ()) () ) () + ( ListAccess + ( Identifier + "a" + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 1 } + , Literal + (Int + 4 + LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 52 , lpLength = 1 }) + LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 52 , lpLength = 1 } + ) + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 4 } , Binary - ( Concat () - , Literal (String "5" ()) () + ( Concat + LP { lpLine = 4 , lpColumn = 12 , lpStartByte = 61 , lpLength = 2 } + , Literal + (String + "5" + LP { lpLine = 4 , lpColumn = 8 , lpStartByte = 57 , lpLength = 3 }) + LP { lpLine = 4 , lpColumn = 8 , lpStartByte = 57 , lpLength = 3 } , LeftValue - (ListAccess ( Identifier "a" () , Literal (Int 0 ()) () ) ()) () + (ListAccess + ( Identifier + "a" + LP { lpLine = 4 , lpColumn = 15 , lpStartByte = 64 , lpLength = 1 } + , Literal + (Int + 0 + LP + { lpLine = 4 , lpColumn = 17 , lpStartByte = 66 , lpLength = 1 }) + LP { lpLine = 4 , lpColumn = 17 , lpStartByte = 66 , lpLength = 1 } + ) + LP + { lpLine = 4 , lpColumn = 15 , lpStartByte = 64 , lpLength = 4 }) + LP { lpLine = 4 , lpColumn = 15 , lpStartByte = 64 , lpLength = 4 } ) - () + LP { lpLine = 4 , lpColumn = 8 , lpStartByte = 57 , lpLength = 11 } ) - ()) - ()) - () + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 18 }) + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 19 }) + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 19 } , Statement (Expression (Call ( "println" , [ LeftValue - (ListAccess ( Identifier "a" () , Literal (Int 0 ()) () ) ()) () + (ListAccess + ( Identifier + "a" + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 1 } + , Literal + (Int + 0 + LP + { lpLine = 5 , lpColumn = 11 , lpStartByte = 80 , lpLength = 1 }) + LP { lpLine = 5 , lpColumn = 11 , lpStartByte = 80 , lpLength = 1 } + ) + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 4 }) + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 4 } , LeftValue - (ListAccess ( Identifier "a" () , Literal (Int 1 ()) () ) ()) () + (ListAccess + ( Identifier + "a" + LP { lpLine = 5 , lpColumn = 15 , lpStartByte = 84 , lpLength = 1 } + , Literal + (Int + 1 + LP + { lpLine = 5 , lpColumn = 17 , lpStartByte = 86 , lpLength = 1 }) + LP { lpLine = 5 , lpColumn = 17 , lpStartByte = 86 , lpLength = 1 } + ) + LP + { lpLine = 5 , lpColumn = 15 , lpStartByte = 84 , lpLength = 4 }) + LP { lpLine = 5 , lpColumn = 15 , lpStartByte = 84 , lpLength = 4 } , LeftValue - (ListAccess ( Identifier "a" () , Literal (Int 2 ()) () ) ()) () + (ListAccess + ( Identifier + "a" + LP { lpLine = 5 , lpColumn = 21 , lpStartByte = 90 , lpLength = 1 } + , Literal + (Int + 2 + LP + { lpLine = 5 , lpColumn = 23 , lpStartByte = 92 , lpLength = 1 }) + LP { lpLine = 5 , lpColumn = 23 , lpStartByte = 92 , lpLength = 1 } + ) + LP + { lpLine = 5 , lpColumn = 21 , lpStartByte = 90 , lpLength = 4 }) + LP { lpLine = 5 , lpColumn = 21 , lpStartByte = 90 , lpLength = 4 } , LeftValue - (ListAccess ( Identifier "a" () , Literal (Int 3 ()) () ) ()) () + (ListAccess + ( Identifier + "a" + LP { lpLine = 5 , lpColumn = 27 , lpStartByte = 96 , lpLength = 1 } + , Literal + (Int + 3 + LP + { lpLine = 5 , lpColumn = 29 , lpStartByte = 98 , lpLength = 1 }) + LP { lpLine = 5 , lpColumn = 29 , lpStartByte = 98 , lpLength = 1 } + ) + LP + { lpLine = 5 , lpColumn = 27 , lpStartByte = 96 , lpLength = 4 }) + LP { lpLine = 5 , lpColumn = 27 , lpStartByte = 96 , lpLength = 4 } , LeftValue - (ListAccess ( Identifier "a" () , Literal (Int 4 ()) () ) ()) () + (ListAccess + ( Identifier + "a" + LP + { lpLine = 5 , lpColumn = 33 , lpStartByte = 102 , lpLength = 1 } + , Literal + (Int + 4 + LP + { lpLine = 5 , lpColumn = 35 , lpStartByte = 104 , lpLength = 1 }) + LP + { lpLine = 5 , lpColumn = 35 , lpStartByte = 104 , lpLength = 1 } + ) + LP + { lpLine = 5 , lpColumn = 33 , lpStartByte = 102 , lpLength = 4 }) + LP + { lpLine = 5 , lpColumn = 33 , lpStartByte = 102 , lpLength = 4 } ] ) - ()) - ()) - () + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 37 }) + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 38 }) + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 38 } , Statement (Expression (Assign - ( Identifier "a" () + ( Identifier + "a" + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 1 } , Literal (List - [ Literal (Int 1 ()) () - , Literal (Int 2 ()) () - , Literal (Int 3 ()) () + [ Literal + (Int + 1 + LP + { lpLine = 6 , lpColumn = 6 , lpStartByte = 114 , lpLength = 1 }) + LP { lpLine = 6 , lpColumn = 6 , lpStartByte = 114 , lpLength = 1 } + , Literal + (Int + 2 + LP + { lpLine = 6 , lpColumn = 9 , lpStartByte = 117 , lpLength = 1 }) + LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 117 , lpLength = 1 } + , Literal + (Int + 3 + LP + { lpLine = 6 , lpColumn = 12 , lpStartByte = 120 , lpLength = 1 }) + LP + { lpLine = 6 , lpColumn = 12 , lpStartByte = 120 , lpLength = 1 } ] - ()) - () + LP + { lpLine = 6 , lpColumn = 5 , lpStartByte = 113 , lpLength = 1 }) + LP { lpLine = 6 , lpColumn = 5 , lpStartByte = 113 , lpLength = 1 } ) - ()) - ()) - () + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 5 }) + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 14 }) + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 14 } , Statement (Expression (Call ( "println" , [ LeftValue - (ListAccess ( Identifier "a" () , Literal (Int 0 ()) () ) ()) () + (ListAccess + ( Identifier + "a" + LP { lpLine = 7 , lpColumn = 9 , lpStartByte = 132 , lpLength = 1 } + , Literal + (Int + 0 + LP + { lpLine = 7 , lpColumn = 11 , lpStartByte = 134 , lpLength = 1 }) + LP + { lpLine = 7 , lpColumn = 11 , lpStartByte = 134 , lpLength = 1 } + ) + LP + { lpLine = 7 , lpColumn = 9 , lpStartByte = 132 , lpLength = 4 }) + LP { lpLine = 7 , lpColumn = 9 , lpStartByte = 132 , lpLength = 4 } , LeftValue - (ListAccess ( Identifier "a" () , Literal (Int 1 ()) () ) ()) () + (ListAccess + ( Identifier + "a" + LP + { lpLine = 7 , lpColumn = 15 , lpStartByte = 138 , lpLength = 1 } + , Literal + (Int + 1 + LP + { lpLine = 7 , lpColumn = 17 , lpStartByte = 140 , lpLength = 1 }) + LP + { lpLine = 7 , lpColumn = 17 , lpStartByte = 140 , lpLength = 1 } + ) + LP + { lpLine = 7 , lpColumn = 15 , lpStartByte = 138 , lpLength = 4 }) + LP + { lpLine = 7 , lpColumn = 15 , lpStartByte = 138 , lpLength = 4 } , LeftValue - (ListAccess ( Identifier "a" () , Literal (Int 2 ()) () ) ()) () + (ListAccess + ( Identifier + "a" + LP + { lpLine = 7 , lpColumn = 21 , lpStartByte = 144 , lpLength = 1 } + , Literal + (Int + 2 + LP + { lpLine = 7 , lpColumn = 23 , lpStartByte = 146 , lpLength = 1 }) + LP + { lpLine = 7 , lpColumn = 23 , lpStartByte = 146 , lpLength = 1 } + ) + LP + { lpLine = 7 , lpColumn = 21 , lpStartByte = 144 , lpLength = 4 }) + LP + { lpLine = 7 , lpColumn = 21 , lpStartByte = 144 , lpLength = 4 } ] ) - ()) - ()) - () + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 124 , lpLength = 25 }) + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 124 , lpLength = 26 }) + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 124 , lpLength = 26 } , Statement (Expression (Call ( "println" , [ Binary - ( Multiply () + ( Multiply + LP + { lpLine = 8 , lpColumn = 24 , lpStartByte = 174 , lpLength = 1 } , Binary - ( Concat () - , Literal (String "10" ()) () + ( Concat + LP + { lpLine = 8 , lpColumn = 15 , lpStartByte = 165 , lpLength = 2 } + , Literal + (String + "10" + LP + { lpLine = 8 , lpColumn = 10 , lpStartByte = 160 , lpLength = 4 }) + LP + { lpLine = 8 , lpColumn = 10 , lpStartByte = 160 , lpLength = 4 } , LeftValue - (ListAccess ( Identifier "a" () , Literal (Int 0 ()) () ) ()) () + (ListAccess + ( Identifier + "a" + LP + { lpLine = 8 , lpColumn = 18 , lpStartByte = 168 , lpLength = 1 } + , Literal + (Int + 0 + LP + { lpLine = 8 + , lpColumn = 20 + , lpStartByte = 170 + , lpLength = 1 + }) + LP + { lpLine = 8 , lpColumn = 20 , lpStartByte = 170 , lpLength = 1 } + ) + LP + { lpLine = 8 , lpColumn = 18 , lpStartByte = 168 , lpLength = 4 }) + LP + { lpLine = 8 , lpColumn = 18 , lpStartByte = 168 , lpLength = 4 } ) - () - , Literal (Int 2 ()) () + LP + { lpLine = 8 , lpColumn = 10 , lpStartByte = 160 , lpLength = 12 } + , Literal + (Int + 2 + LP + { lpLine = 8 , lpColumn = 26 , lpStartByte = 176 , lpLength = 1 }) + LP + { lpLine = 8 , lpColumn = 26 , lpStartByte = 176 , lpLength = 1 } ) - () + LP + { lpLine = 8 , lpColumn = 10 , lpStartByte = 160 , lpLength = 17 } ] ) - ()) - ()) - () + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 151 , lpLength = 27 }) + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 151 , lpLength = 28 }) + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 151 , lpLength = 28 } , Statement (Expression (Call ( "println" - , [ Call ( "len" , [ LeftValue (Identifier "a" ()) () ] ) () ] + , [ Call + ( "len" + , [ LeftValue + (Identifier + "a" + LP + { lpLine = 9 , lpColumn = 13 , lpStartByte = 192 , lpLength = 1 }) + LP + { lpLine = 9 , lpColumn = 13 , lpStartByte = 192 , lpLength = 1 } + ] + ) + LP { lpLine = 9 , lpColumn = 9 , lpStartByte = 188 , lpLength = 6 } + ] ) - ()) - ()) - () + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 180 , lpLength = 15 }) + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 180 , lpLength = 16 }) + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 180 , lpLength = 16 } , Statement (Expression (Call ( "println" , [ Binary - ( Multiply () - , Call ( "len" , [ LeftValue (Identifier "a" ()) () ] ) () - , Literal (Int 8 ()) () + ( Multiply + LP + { lpLine = 10 , lpColumn = 16 , lpStartByte = 212 , lpLength = 1 } + , Call + ( "len" + , [ LeftValue + (Identifier + "a" + LP + { lpLine = 10 , lpColumn = 13 , lpStartByte = 209 , lpLength = 1 }) + LP + { lpLine = 10 , lpColumn = 13 , lpStartByte = 209 , lpLength = 1 } + ] + ) + LP + { lpLine = 10 , lpColumn = 9 , lpStartByte = 205 , lpLength = 6 } + , Literal + (Int + 8 + LP + { lpLine = 10 , lpColumn = 18 , lpStartByte = 214 , lpLength = 1 }) + LP + { lpLine = 10 , lpColumn = 18 , lpStartByte = 214 , lpLength = 1 } ) - () + LP + { lpLine = 10 , lpColumn = 9 , lpStartByte = 205 , lpLength = 10 } ] ) - ()) - ()) - () - , Statement (Comment "println([1, 2, 3]);" ()) () + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 197 , lpLength = 19 }) + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 197 , lpLength = 20 }) + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 197 , lpLength = 20 } + , Statement + (Comment + "println([1, 2, 3]);" + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 218 , lpLength = 21 }) + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 218 , lpLength = 21 } ] - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 239 } diff --git a/test/testcase/Batsh/assignment.ast b/test/testcase/Batsh/assignment.ast index 3e22254..eb84f6f 100644 --- a/test/testcase/Batsh/assignment.ast +++ b/test/testcase/Batsh/assignment.ast @@ -2,73 +2,206 @@ Program [ Statement (Expression (Assign - ( Identifier "a" () + ( Identifier + "a" + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } , Binary - ( Concat () - , Literal (String "Value: " ()) () + ( Concat + LP { lpLine = 1 , lpColumn = 15 , lpStartByte = 14 , lpLength = 2 } + , Literal + (String + "Value: " + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 9 }) + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 9 } , Binary - ( Plus () - , Literal (Int 1 ()) () + ( Plus + LP { lpLine = 1 , lpColumn = 20 , lpStartByte = 19 , lpLength = 1 } + , Literal + (Int + 1 + LP + { lpLine = 1 , lpColumn = 18 , lpStartByte = 17 , lpLength = 1 }) + LP { lpLine = 1 , lpColumn = 18 , lpStartByte = 17 , lpLength = 1 } , Binary - ( Multiply () + ( Multiply + LP { lpLine = 1 , lpColumn = 30 , lpStartByte = 29 , lpLength = 1 } , Binary - ( Plus () , Literal (Int 4 ()) () , Literal (Int 6 ()) () ) () - , Literal (Int 3 ()) () + ( Plus + LP { lpLine = 1 , lpColumn = 25 , lpStartByte = 24 , lpLength = 1 } + , Literal + (Int + 4 + LP + { lpLine = 1 + , lpColumn = 23 + , lpStartByte = 22 + , lpLength = 1 + }) + LP { lpLine = 1 , lpColumn = 23 , lpStartByte = 22 , lpLength = 1 } + , Literal + (Int + 6 + LP + { lpLine = 1 + , lpColumn = 27 + , lpStartByte = 26 + , lpLength = 1 + }) + LP { lpLine = 1 , lpColumn = 27 , lpStartByte = 26 , lpLength = 1 } + ) + LP { lpLine = 1 , lpColumn = 23 , lpStartByte = 22 , lpLength = 5 } + , Literal + (Int + 3 + LP + { lpLine = 1 , lpColumn = 32 , lpStartByte = 31 , lpLength = 1 }) + LP { lpLine = 1 , lpColumn = 32 , lpStartByte = 31 , lpLength = 1 } ) - () + LP + { lpLine = 1 , lpColumn = 23 , lpStartByte = 22 , lpLength = 10 } ) - () + LP + { lpLine = 1 , lpColumn = 18 , lpStartByte = 17 , lpLength = 15 } ) - () + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 28 } ) - ()) - ()) - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 32 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "a" ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ LeftValue + (Identifier + "a" + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 42 , lpLength = 1 }) + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 42 , lpLength = 1 } + ] + ) + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 34 , lpLength = 10 }) + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 34 , lpLength = 11 }) + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 34 , lpLength = 11 } , Statement (Expression (Assign - ( Identifier "b" () + ( Identifier + "b" + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 1 } , Binary - ( Plus () , Literal (Int 3 ()) () , Literal (Int 4 ()) () ) () + ( Plus + LP { lpLine = 3 , lpColumn = 7 , lpStartByte = 52 , lpLength = 1 } + , Literal + (Int + 3 + LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 50 , lpLength = 1 }) + LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 50 , lpLength = 1 } + , Literal + (Int + 4 + LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 54 , lpLength = 1 }) + LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 54 , lpLength = 1 } + ) + LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 50 , lpLength = 5 } ) - ()) - ()) - () + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 9 }) + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 10 }) + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 10 } , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "b" ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ LeftValue + (Identifier + "b" + LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 65 , lpLength = 1 }) + LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 65 , lpLength = 1 } + ] + ) + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 57 , lpLength = 10 }) + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 57 , lpLength = 11 }) + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 57 , lpLength = 11 } , Statement (Expression (Assign - ( Identifier "c" () , LeftValue (Identifier "a" ()) () ) ()) - ()) - () + ( Identifier + "c" + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 1 } + , LeftValue + (Identifier + "a" + LP { lpLine = 5 , lpColumn = 5 , lpStartByte = 73 , lpLength = 1 }) + LP { lpLine = 5 , lpColumn = 5 , lpStartByte = 73 , lpLength = 1 } + ) + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 5 }) + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 6 }) + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 6 } , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "c" ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ LeftValue + (Identifier + "c" + LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 84 , lpLength = 1 }) + LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 84 , lpLength = 1 } + ] + ) + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 76 , lpLength = 10 }) + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 76 , lpLength = 11 }) + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 76 , lpLength = 11 } , Statement (Expression (Assign - ( Identifier "d" () + ( Identifier + "d" + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 1 } , Binary - ( Concat () - , LeftValue (Identifier "b" ()) () - , LeftValue (Identifier "c" ()) () + ( Concat + LP { lpLine = 7 , lpColumn = 7 , lpStartByte = 94 , lpLength = 2 } + , LeftValue + (Identifier + "b" + LP { lpLine = 7 , lpColumn = 5 , lpStartByte = 92 , lpLength = 1 }) + LP { lpLine = 7 , lpColumn = 5 , lpStartByte = 92 , lpLength = 1 } + , LeftValue + (Identifier + "c" + LP + { lpLine = 7 , lpColumn = 10 , lpStartByte = 97 , lpLength = 1 }) + LP { lpLine = 7 , lpColumn = 10 , lpStartByte = 97 , lpLength = 1 } ) - () + LP { lpLine = 7 , lpColumn = 5 , lpStartByte = 92 , lpLength = 6 } ) - ()) - ()) - () + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 10 }) + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 11 }) + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 11 } , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "d" ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ LeftValue + (Identifier + "d" + LP + { lpLine = 8 , lpColumn = 9 , lpStartByte = 108 , lpLength = 1 }) + LP { lpLine = 8 , lpColumn = 9 , lpStartByte = 108 , lpLength = 1 } + ] + ) + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 100 , lpLength = 10 }) + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 100 , lpLength = 11 }) + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 100 , lpLength = 11 } ] - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 111 } diff --git a/test/testcase/Batsh/block.ast b/test/testcase/Batsh/block.ast index 08bfa2a..cdd56ab 100644 --- a/test/testcase/Batsh/block.ast +++ b/test/testcase/Batsh/block.ast @@ -1,30 +1,103 @@ Program - [ Statement (Comment "Level 0 Start" ()) () + [ Statement + (Comment + "Level 0 Start" + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 } , Statement (Expression - (Call ( "println" , [ Literal (String "Hello" ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ Literal + (String + "Hello" + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 24 , lpLength = 7 }) + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 24 , lpLength = 7 } + ] + ) + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 16 }) + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 17 }) + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 17 } , Statement (Block - [ Comment "Level 1 Start" () + [ Comment + "Level 1 Start" + LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 38 , lpLength = 15 } , Expression - (Call ( "println" , [ Literal (String "Lo" ()) () ] ) ()) () + (Call + ( "println" + , [ Literal + (String + "Lo" + LP + { lpLine = 5 , lpColumn = 11 , lpStartByte = 64 , lpLength = 4 }) + LP { lpLine = 5 , lpColumn = 11 , lpStartByte = 64 , lpLength = 4 } + ] + ) + LP + { lpLine = 5 , lpColumn = 3 , lpStartByte = 56 , lpLength = 13 }) + LP { lpLine = 5 , lpColumn = 3 , lpStartByte = 56 , lpLength = 14 } , Block - [ Comment "Level 2 Start" () + [ Comment + "Level 2 Start" + LP { lpLine = 7 , lpColumn = 5 , lpStartByte = 79 , lpLength = 15 } , Expression - (Call ( "println" , [ Literal (String "and behold" ()) () ] ) ()) - () - , Comment "Level 2 End" () + (Call + ( "println" + , [ Literal + (String + "and behold" + LP + { lpLine = 8 , lpColumn = 13 , lpStartByte = 107 , lpLength = 12 }) + LP + { lpLine = 8 , lpColumn = 13 , lpStartByte = 107 , lpLength = 12 } + ] + ) + LP + { lpLine = 8 , lpColumn = 5 , lpStartByte = 99 , lpLength = 21 }) + LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 99 , lpLength = 22 } + , Comment + "Level 2 End" + LP + { lpLine = 9 , lpColumn = 5 , lpStartByte = 126 , lpLength = 13 } ] - () - , Comment "Level 1 End" () + LP { lpLine = 6 , lpColumn = 3 , lpStartByte = 73 , lpLength = 70 } + , Comment + "Level 1 End" + LP + { lpLine = 11 , lpColumn = 3 , lpStartByte = 146 , lpLength = 13 } ] - ()) - () + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 34 , lpLength = 127 }) + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 34 , lpLength = 127 } , Statement (Expression - (Call ( "println" , [ Literal (String "End" ()) () ] ) ()) ()) - () - , Statement (Comment "Level 0 End" ()) () + (Call + ( "println" + , [ Literal + (String + "End" + LP + { lpLine = 13 , lpColumn = 9 , lpStartByte = 170 , lpLength = 5 }) + LP + { lpLine = 13 , lpColumn = 9 , lpStartByte = 170 , lpLength = 5 } + ] + ) + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 162 , lpLength = 14 }) + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 162 , lpLength = 15 }) + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 162 , lpLength = 15 } + , Statement + (Comment + "Level 0 End" + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 178 , lpLength = 13 }) + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 178 , lpLength = 13 } ] - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 191 } diff --git a/test/testcase/Batsh/command.ast b/test/testcase/Batsh/command.ast index 7c714aa..df8b79d 100644 --- a/test/testcase/Batsh/command.ast +++ b/test/testcase/Batsh/command.ast @@ -3,51 +3,116 @@ Program (Expression (Call ( "call" - , [ Literal (String "println" ()) () - , Literal (String "Println Called" ()) () + , [ Literal + (String + "println" + LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 9 }) + LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 9 } + , Literal + (String + "Println Called" + LP + { lpLine = 1 , lpColumn = 17 , lpStartByte = 16 , lpLength = 16 }) + LP + { lpLine = 1 , lpColumn = 17 , lpStartByte = 16 , lpLength = 16 } ] ) - ()) - ()) - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 34 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 34 } , Statement (Expression (Assign - ( Identifier "cmd" () + ( Identifier + "cmd" + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 3 } , Binary - ( Concat () - , Literal (String "ec" ()) () - , Literal (String "ho" ()) () + ( Concat + LP { lpLine = 2 , lpColumn = 12 , lpStartByte = 46 , lpLength = 2 } + , Literal + (String + "ec" + LP { lpLine = 2 , lpColumn = 7 , lpStartByte = 41 , lpLength = 4 }) + LP { lpLine = 2 , lpColumn = 7 , lpStartByte = 41 , lpLength = 4 } + , Literal + (String + "ho" + LP + { lpLine = 2 , lpColumn = 15 , lpStartByte = 49 , lpLength = 4 }) + LP { lpLine = 2 , lpColumn = 15 , lpStartByte = 49 , lpLength = 4 } ) - () + LP { lpLine = 2 , lpColumn = 7 , lpStartByte = 41 , lpLength = 12 } ) - ()) - ()) - () + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 18 }) + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 19 }) + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 19 } , Statement (Expression (Call ( "call" - , [ LeftValue (Identifier "cmd" ()) () - , Literal (String "Echo Called" ()) () + , [ LeftValue + (Identifier + "cmd" + LP { lpLine = 3 , lpColumn = 6 , lpStartByte = 60 , lpLength = 3 }) + LP { lpLine = 3 , lpColumn = 6 , lpStartByte = 60 , lpLength = 3 } + , Literal + (String + "Echo Called" + LP + { lpLine = 3 , lpColumn = 11 , lpStartByte = 65 , lpLength = 13 }) + LP + { lpLine = 3 , lpColumn = 11 , lpStartByte = 65 , lpLength = 13 } ] ) - ()) - ()) - () + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 55 , lpLength = 24 }) + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 55 , lpLength = 25 }) + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 55 , lpLength = 25 } , Statement (Expression (Assign - ( Identifier "retval" () - , Call ( "echo" , [ Literal (String "Value 100%" ()) () ] ) () + ( Identifier + "retval" + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 6 } + , Call + ( "echo" + , [ Literal + (String + "Value 100%" + LP + { lpLine = 4 , lpColumn = 15 , lpStartByte = 95 , lpLength = 12 }) + LP + { lpLine = 4 , lpColumn = 15 , lpStartByte = 95 , lpLength = 12 } + ] + ) + LP + { lpLine = 4 , lpColumn = 10 , lpStartByte = 90 , lpLength = 18 } ) - ()) - ()) - () + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 27 }) + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 28 }) + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 28 } , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "retval" ()) () ] ) ()) - ()) - () + (Call + ( "println" + , [ LeftValue + (Identifier + "retval" + LP + { lpLine = 5 , lpColumn = 9 , lpStartByte = 118 , lpLength = 6 }) + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 118 , lpLength = 6 } + ] + ) + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 110 , lpLength = 15 }) + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 110 , lpLength = 16 }) + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 110 , lpLength = 16 } ] - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 126 } diff --git a/test/testcase/Batsh/comment.ast b/test/testcase/Batsh/comment.ast index 1defe64..e92b33c 100644 --- a/test/testcase/Batsh/comment.ast +++ b/test/testcase/Batsh/comment.ast @@ -1,28 +1,77 @@ Program [ Statement (Expression - (Assign ( Identifier "a" () , Literal (Int 3 ()) () ) ()) ()) - () - , Statement (Comment " This is comment 1" ()) () + (Assign + ( Identifier + "a" + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } + , Literal + (Int + 3 + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 }) + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } + ) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 5 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 } + , Statement + (Comment + " This is comment 1" + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 20 }) + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 20 } , Statement (Expression (Assign - ( Identifier "a" () + ( Identifier + "a" + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 1 } , Binary - ( Multiply () - , LeftValue (Identifier "a" ()) () - , Literal (Int 5 ()) () + ( Multiply + LP { lpLine = 3 , lpColumn = 7 , lpStartByte = 34 , lpLength = 1 } + , LeftValue + (Identifier + "a" + LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 32 , lpLength = 1 }) + LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 32 , lpLength = 1 } + , Literal + (Int + 5 + LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 36 , lpLength = 1 }) + LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 36 , lpLength = 1 } ) - () + LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 32 , lpLength = 5 } ) - ()) - ()) - () - , Statement (Comment " This is comment 2" ()) () + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 9 }) + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 10 }) + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 10 } + , Statement + (Comment + " This is comment 2" + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 39 , lpLength = 20 }) + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 39 , lpLength = 20 } , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "a" ()) () ] ) ()) ()) - () - , Statement (Comment "This is comment 3" ()) () + (Call + ( "println" + , [ LeftValue + (Identifier + "a" + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 68 , lpLength = 1 }) + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 68 , lpLength = 1 } + ] + ) + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 60 , lpLength = 10 }) + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 60 , lpLength = 11 }) + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 60 , lpLength = 11 } + , Statement + (Comment + "This is comment 3" + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 72 , lpLength = 19 }) + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 72 , lpLength = 19 } ] - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 91 } diff --git a/test/testcase/Batsh/exists.ast b/test/testcase/Batsh/exists.ast index 881c9ac..3b7abfc 100644 --- a/test/testcase/Batsh/exists.ast +++ b/test/testcase/Batsh/exists.ast @@ -2,47 +2,153 @@ Program [ Statement (Expression (Assign - ( Identifier "ex" () - , Call ( "exists" , [ Literal (String "Makefile" ()) () ] ) () + ( Identifier + "ex" + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 2 } + , Call + ( "exists" + , [ Literal + (String + "Makefile" + LP + { lpLine = 1 , lpColumn = 13 , lpStartByte = 12 , lpLength = 10 }) + LP + { lpLine = 1 , lpColumn = 13 , lpStartByte = 12 , lpLength = 10 } + ] + ) + LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 18 } ) - ()) - ()) - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 23 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 24 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 24 } , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "ex" ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ LeftValue + (Identifier + "ex" + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 33 , lpLength = 2 }) + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 33 , lpLength = 2 } + ] + ) + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 25 , lpLength = 11 }) + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 25 , lpLength = 12 }) + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 25 , lpLength = 12 } , Statement (Expression - (Call ( "exists" , [ Literal (String "Makefile" ()) () ] ) ()) ()) - () + (Call + ( "exists" + , [ Literal + (String + "Makefile" + LP + { lpLine = 3 , lpColumn = 8 , lpStartByte = 45 , lpLength = 10 }) + LP { lpLine = 3 , lpColumn = 8 , lpStartByte = 45 , lpLength = 10 } + ] + ) + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 18 }) + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 19 }) + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 19 } , Statement (If - ( Call ( "exists" , [ Literal (String "Makefile" ()) () ] ) () + ( Call + ( "exists" + , [ Literal + (String + "Makefile" + LP + { lpLine = 4 , lpColumn = 12 , lpStartByte = 69 , lpLength = 10 }) + LP + { lpLine = 4 , lpColumn = 12 , lpStartByte = 69 , lpLength = 10 } + ] + ) + LP { lpLine = 4 , lpColumn = 5 , lpStartByte = 62 , lpLength = 18 } , Block [ Expression - (Call ( "println" , [ Literal (String "Yes" ()) () ] ) ()) () + (Call + ( "println" + , [ Literal + (String + "Yes" + LP + { lpLine = 5 , lpColumn = 11 , lpStartByte = 94 , lpLength = 5 }) + LP { lpLine = 5 , lpColumn = 11 , lpStartByte = 94 , lpLength = 5 } + ] + ) + LP + { lpLine = 5 , lpColumn = 3 , lpStartByte = 86 , lpLength = 14 }) + LP { lpLine = 5 , lpColumn = 3 , lpStartByte = 86 , lpLength = 15 } ] - () + LP + { lpLine = 4 , lpColumn = 25 , lpStartByte = 82 , lpLength = 21 } ) - ()) - () + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 58 , lpLength = 45 }) + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 58 , lpLength = 45 } , Statement (IfElse - ( Call ( "exists" , [ Literal (String "none" ()) () ] ) () + ( Call + ( "exists" + , [ Literal + (String + "none" + LP + { lpLine = 7 , lpColumn = 12 , lpStartByte = 115 , lpLength = 6 }) + LP + { lpLine = 7 , lpColumn = 12 , lpStartByte = 115 , lpLength = 6 } + ] + ) + LP + { lpLine = 7 , lpColumn = 5 , lpStartByte = 108 , lpLength = 14 } , Block [ Expression - (Call ( "println" , [ Literal (String "Impossible" ()) () ] ) ()) - () + (Call + ( "println" + , [ Literal + (String + "Impossible" + LP + { lpLine = 8 , lpColumn = 11 , lpStartByte = 136 , lpLength = 12 }) + LP + { lpLine = 8 , lpColumn = 11 , lpStartByte = 136 , lpLength = 12 } + ] + ) + LP + { lpLine = 8 , lpColumn = 3 , lpStartByte = 128 , lpLength = 21 }) + LP + { lpLine = 8 , lpColumn = 3 , lpStartByte = 128 , lpLength = 22 } ] - () + LP + { lpLine = 7 , lpColumn = 21 , lpStartByte = 124 , lpLength = 28 } , Block [ Expression - (Call ( "println" , [ Literal (String "No" ()) () ] ) ()) () + (Call + ( "println" + , [ Literal + (String + "No" + LP + { lpLine = 10 , lpColumn = 11 , lpStartByte = 170 , lpLength = 4 }) + LP + { lpLine = 10 , lpColumn = 11 , lpStartByte = 170 , lpLength = 4 } + ] + ) + LP + { lpLine = 10 , lpColumn = 3 , lpStartByte = 162 , lpLength = 13 }) + LP + { lpLine = 10 , lpColumn = 3 , lpStartByte = 162 , lpLength = 14 } ] - () + LP + { lpLine = 9 , lpColumn = 8 , lpStartByte = 158 , lpLength = 20 } ) - ()) - () + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 104 , lpLength = 74 }) + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 104 , lpLength = 74 } ] - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 178 } diff --git a/test/testcase/Batsh/function.ast b/test/testcase/Batsh/function.ast index bf98a6d..3a1ec48 100644 --- a/test/testcase/Batsh/function.ast +++ b/test/testcase/Batsh/function.ast @@ -1,159 +1,508 @@ Program - [ Statement (Comment " Function call" ()) () + [ Statement + (Comment + " Function call" + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 16 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 16 } , Function ( "func1" , [ "p1" , "p2" ] , [ Expression (Call ( "println" - , [ LeftValue (Identifier "p1" ()) () - , LeftValue (Identifier "p2" ()) () + , [ LeftValue + (Identifier + "p1" + LP + { lpLine = 3 , lpColumn = 11 , lpStartByte = 52 , lpLength = 2 }) + LP { lpLine = 3 , lpColumn = 11 , lpStartByte = 52 , lpLength = 2 } + , LeftValue + (Identifier + "p2" + LP + { lpLine = 3 , lpColumn = 15 , lpStartByte = 56 , lpLength = 2 }) + LP { lpLine = 3 , lpColumn = 15 , lpStartByte = 56 , lpLength = 2 } ] ) - ()) - () + LP + { lpLine = 3 , lpColumn = 3 , lpStartByte = 44 , lpLength = 15 }) + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 44 , lpLength = 16 } ] ) - () + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 17 , lpLength = 45 } , Statement (Expression (Call ( "func1" - , [ Literal (String "Hello" ()) () - , Literal (String "World" ()) () + , [ Literal + (String + "Hello" + LP { lpLine = 5 , lpColumn = 7 , lpStartByte = 69 , lpLength = 7 }) + LP { lpLine = 5 , lpColumn = 7 , lpStartByte = 69 , lpLength = 7 } + , Literal + (String + "World" + LP + { lpLine = 5 , lpColumn = 16 , lpStartByte = 78 , lpLength = 7 }) + LP { lpLine = 5 , lpColumn = 16 , lpStartByte = 78 , lpLength = 7 } ] ) - ()) - ()) - () - , Statement (Comment " Global and local variables" ()) () + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 63 , lpLength = 23 }) + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 63 , lpLength = 24 }) + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 63 , lpLength = 24 } + , Statement + (Comment + " Global and local variables" + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 88 , lpLength = 29 }) + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 88 , lpLength = 29 } , Statement (Expression (Assign - ( Identifier "v1" () , Literal (String "Global V1" ()) () ) ()) - ()) - () + ( Identifier + "v1" + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 2 } + , Literal + (String + "Global V1" + LP + { lpLine = 7 , lpColumn = 6 , lpStartByte = 123 , lpLength = 11 }) + LP + { lpLine = 7 , lpColumn = 6 , lpStartByte = 123 , lpLength = 11 } + ) + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 16 }) + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 17 }) + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 17 } , Statement (Expression (Assign - ( Identifier "v2" () , Literal (String "Global V2" ()) () ) ()) - ()) - () + ( Identifier + "v2" + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 2 } + , Literal + (String + "Global V2" + LP + { lpLine = 8 , lpColumn = 6 , lpStartByte = 141 , lpLength = 11 }) + LP + { lpLine = 8 , lpColumn = 6 , lpStartByte = 141 , lpLength = 11 } + ) + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 16 }) + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 17 }) + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 17 } , Statement (Expression (Assign - ( Identifier "v3" () , Literal (String "Global V3" ()) () ) ()) - ()) - () + ( Identifier + "v3" + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 2 } + , Literal + (String + "Global V3" + LP + { lpLine = 9 , lpColumn = 6 , lpStartByte = 159 , lpLength = 11 }) + LP + { lpLine = 9 , lpColumn = 6 , lpStartByte = 159 , lpLength = 11 } + ) + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 16 }) + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 17 }) + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 17 } , Function ( "func2" , [ "p" ] , [ Expression (Assign - ( Identifier "v1" () + ( Identifier + "v1" + LP + { lpLine = 11 , lpColumn = 3 , lpStartByte = 194 , lpLength = 2 } , Binary - ( Concat () - , Literal (String "Local " ()) () - , LeftValue (Identifier "p" ()) () + ( Concat + LP + { lpLine = 11 , lpColumn = 17 , lpStartByte = 208 , lpLength = 2 } + , Literal + (String + "Local " + LP + { lpLine = 11 , lpColumn = 8 , lpStartByte = 199 , lpLength = 8 }) + LP + { lpLine = 11 , lpColumn = 8 , lpStartByte = 199 , lpLength = 8 } + , LeftValue + (Identifier + "p" + LP + { lpLine = 11 , lpColumn = 20 , lpStartByte = 211 , lpLength = 1 }) + LP + { lpLine = 11 , lpColumn = 20 , lpStartByte = 211 , lpLength = 1 } ) - () + LP + { lpLine = 11 , lpColumn = 8 , lpStartByte = 199 , lpLength = 13 } ) - ()) - () + LP + { lpLine = 11 , lpColumn = 3 , lpStartByte = 194 , lpLength = 18 }) + LP + { lpLine = 11 , lpColumn = 3 , lpStartByte = 194 , lpLength = 19 } , Expression - (Call ( "println" , [ LeftValue (Identifier "v1" ()) () ] ) ()) () + (Call + ( "println" + , [ LeftValue + (Identifier + "v1" + LP + { lpLine = 12 , lpColumn = 11 , lpStartByte = 224 , lpLength = 2 }) + LP + { lpLine = 12 , lpColumn = 11 , lpStartByte = 224 , lpLength = 2 } + ] + ) + LP + { lpLine = 12 , lpColumn = 3 , lpStartByte = 216 , lpLength = 11 }) + LP + { lpLine = 12 , lpColumn = 3 , lpStartByte = 216 , lpLength = 12 } , Expression - (Call ( "println" , [ LeftValue (Identifier "v2" ()) () ] ) ()) () - , Global "v3" () - , Global "v4" () + (Call + ( "println" + , [ LeftValue + (Identifier + "v2" + LP + { lpLine = 13 , lpColumn = 11 , lpStartByte = 239 , lpLength = 2 }) + LP + { lpLine = 13 , lpColumn = 11 , lpStartByte = 239 , lpLength = 2 } + ] + ) + LP + { lpLine = 13 , lpColumn = 3 , lpStartByte = 231 , lpLength = 11 }) + LP + { lpLine = 13 , lpColumn = 3 , lpStartByte = 231 , lpLength = 12 } + , Global + "v3" + LP + { lpLine = 14 , lpColumn = 3 , lpStartByte = 246 , lpLength = 10 } + , Global + "v4" + LP + { lpLine = 15 , lpColumn = 3 , lpStartByte = 259 , lpLength = 10 } , Expression (Assign - ( Identifier "v3" () , Literal (String "V3 Modified." ()) () ) ()) - () + ( Identifier + "v3" + LP + { lpLine = 16 , lpColumn = 3 , lpStartByte = 272 , lpLength = 2 } + , Literal + (String + "V3 Modified." + LP + { lpLine = 16 , lpColumn = 8 , lpStartByte = 277 , lpLength = 14 }) + LP + { lpLine = 16 , lpColumn = 8 , lpStartByte = 277 , lpLength = 14 } + ) + LP + { lpLine = 16 , lpColumn = 3 , lpStartByte = 272 , lpLength = 19 }) + LP + { lpLine = 16 , lpColumn = 3 , lpStartByte = 272 , lpLength = 20 } ] ) - () + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 172 , lpLength = 122 } , Statement (Expression - (Call ( "func2" , [ Literal (String "Var" ()) () ] ) ()) ()) - () + (Call + ( "func2" + , [ Literal + (String + "Var" + LP + { lpLine = 18 , lpColumn = 7 , lpStartByte = 301 , lpLength = 5 }) + LP + { lpLine = 18 , lpColumn = 7 , lpStartByte = 301 , lpLength = 5 } + ] + ) + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 295 , lpLength = 12 }) + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 295 , lpLength = 13 }) + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 295 , lpLength = 13 } , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "v1" ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ LeftValue + (Identifier + "v1" + LP + { lpLine = 19 , lpColumn = 9 , lpStartByte = 317 , lpLength = 2 }) + LP + { lpLine = 19 , lpColumn = 9 , lpStartByte = 317 , lpLength = 2 } + ] + ) + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 309 , lpLength = 11 }) + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 309 , lpLength = 12 }) + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 309 , lpLength = 12 } , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "v3" ()) () ] ) ()) ()) - () - , Statement (Comment " Return value" ()) () + (Call + ( "println" + , [ LeftValue + (Identifier + "v3" + LP + { lpLine = 20 , lpColumn = 9 , lpStartByte = 330 , lpLength = 2 }) + LP + { lpLine = 20 , lpColumn = 9 , lpStartByte = 330 , lpLength = 2 } + ] + ) + LP + { lpLine = 20 , lpColumn = 1 , lpStartByte = 322 , lpLength = 11 }) + LP + { lpLine = 20 , lpColumn = 1 , lpStartByte = 322 , lpLength = 12 }) + LP + { lpLine = 20 , lpColumn = 1 , lpStartByte = 322 , lpLength = 12 } + , Statement + (Comment + " Return value" + LP + { lpLine = 21 , lpColumn = 1 , lpStartByte = 335 , lpLength = 15 }) + LP + { lpLine = 21 , lpColumn = 1 , lpStartByte = 335 , lpLength = 15 } , Function ( "func3" , [ "num" ] , [ Return (Just (Binary - ( Plus () - , LeftValue (Identifier "num" ()) () - , Literal (Int 41 ()) () + ( Plus + LP + { lpLine = 23 , lpColumn = 14 , lpStartByte = 386 , lpLength = 1 } + , LeftValue + (Identifier + "num" + LP + { lpLine = 23 , lpColumn = 10 , lpStartByte = 382 , lpLength = 3 }) + LP + { lpLine = 23 , lpColumn = 10 , lpStartByte = 382 , lpLength = 3 } + , Literal + (Int + 41 + LP + { lpLine = 23 , lpColumn = 16 , lpStartByte = 388 , lpLength = 2 }) + LP + { lpLine = 23 , lpColumn = 16 , lpStartByte = 388 , lpLength = 2 } ) - ())) - () + LP + { lpLine = 23 + , lpColumn = 10 + , lpStartByte = 382 + , lpLength = 8 + })) + LP + { lpLine = 23 , lpColumn = 3 , lpStartByte = 375 , lpLength = 16 } ] ) - () + LP + { lpLine = 22 , lpColumn = 1 , lpStartByte = 351 , lpLength = 42 } , Statement - (Expression (Call ( "func3" , [ Literal (Int 4 ()) () ] ) ()) ()) - () - , Statement (Expression (Call ( "println" , [] ) ()) ()) () + (Expression + (Call + ( "func3" + , [ Literal + (Int + 4 + LP + { lpLine = 25 , lpColumn = 7 , lpStartByte = 400 , lpLength = 1 }) + LP + { lpLine = 25 , lpColumn = 7 , lpStartByte = 400 , lpLength = 1 } + ] + ) + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 394 , lpLength = 8 }) + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 394 , lpLength = 9 }) + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 394 , lpLength = 9 } + , Statement + (Expression + (Call + ( "println" , [] ) + LP + { lpLine = 26 , lpColumn = 1 , lpStartByte = 404 , lpLength = 9 }) + LP + { lpLine = 26 , lpColumn = 1 , lpStartByte = 404 , lpLength = 10 }) + LP + { lpLine = 26 , lpColumn = 1 , lpStartByte = 404 , lpLength = 10 } , Statement (Expression (Assign - ( Identifier "ret" () - , Call ( "func3" , [ Literal (Int 1 ()) () ] ) () + ( Identifier + "ret" + LP + { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 3 } + , Call + ( "func3" + , [ Literal + (Int + 1 + LP + { lpLine = 27 , lpColumn = 13 , lpStartByte = 427 , lpLength = 1 }) + LP + { lpLine = 27 , lpColumn = 13 , lpStartByte = 427 , lpLength = 1 } + ] + ) + LP + { lpLine = 27 , lpColumn = 7 , lpStartByte = 421 , lpLength = 8 } ) - ()) - ()) - () + LP + { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 14 }) + LP + { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 15 }) + LP + { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 15 } , Statement (Expression (Call ( "println" - , [ Literal (String "Returned:" ()) () - , LeftValue (Identifier "ret" ()) () + , [ Literal + (String + "Returned:" + LP + { lpLine = 28 , lpColumn = 9 , lpStartByte = 439 , lpLength = 11 }) + LP + { lpLine = 28 , lpColumn = 9 , lpStartByte = 439 , lpLength = 11 } + , LeftValue + (Identifier + "ret" + LP + { lpLine = 28 , lpColumn = 22 , lpStartByte = 452 , lpLength = 3 }) + LP + { lpLine = 28 , lpColumn = 22 , lpStartByte = 452 , lpLength = 3 } ] ) - ()) - ()) - () - , Statement (Comment " Argument containing space" ()) () + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 431 , lpLength = 25 }) + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 431 , lpLength = 26 }) + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 431 , lpLength = 26 } + , Statement + (Comment + " Argument containing space" + LP + { lpLine = 29 , lpColumn = 1 , lpStartByte = 458 , lpLength = 28 }) + LP + { lpLine = 29 , lpColumn = 1 , lpStartByte = 458 , lpLength = 28 } , Function ( "g" , [ "text" ] - , [ Return (Just (LeftValue (Identifier "text" ()) ())) () ] + , [ Return + (Just + (LeftValue + (Identifier + "text" + LP + { lpLine = 31 , lpColumn = 10 , lpStartByte = 515 , lpLength = 4 }) + LP + { lpLine = 31 + , lpColumn = 10 + , lpStartByte = 515 + , lpLength = 4 + })) + LP + { lpLine = 31 , lpColumn = 3 , lpStartByte = 508 , lpLength = 12 } + ] ) - () + LP + { lpLine = 30 , lpColumn = 1 , lpStartByte = 487 , lpLength = 35 } , Function ( "f" , [ "text" ] , [ Return - (Just (Call ( "g" , [ LeftValue (Identifier "text" ()) () ] ) ())) - () + (Just + (Call + ( "g" + , [ LeftValue + (Identifier + "text" + LP + { lpLine = 34 , lpColumn = 12 , lpStartByte = 553 , lpLength = 4 }) + LP + { lpLine = 34 , lpColumn = 12 , lpStartByte = 553 , lpLength = 4 } + ] + ) + LP + { lpLine = 34 + , lpColumn = 10 + , lpStartByte = 551 + , lpLength = 7 + })) + LP + { lpLine = 34 , lpColumn = 3 , lpStartByte = 544 , lpLength = 15 } ] ) - () + LP + { lpLine = 33 , lpColumn = 1 , lpStartByte = 523 , lpLength = 38 } , Statement (Expression (Assign - ( Identifier "test" () - , Call ( "f" , [ Literal (String "Param with space" ()) () ] ) () + ( Identifier + "test" + LP + { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 4 } + , Call + ( "f" + , [ Literal + (String + "Param with space" + LP + { lpLine = 36 + , lpColumn = 10 + , lpStartByte = 571 + , lpLength = 18 + }) + LP + { lpLine = 36 , lpColumn = 10 , lpStartByte = 571 , lpLength = 18 } + ] + ) + LP + { lpLine = 36 , lpColumn = 8 , lpStartByte = 569 , lpLength = 21 } ) - ()) - ()) - () + LP + { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 28 }) + LP + { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 29 }) + LP + { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 29 } , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "test" ()) () ] ) ()) - ()) - () + (Call + ( "println" + , [ LeftValue + (Identifier + "test" + LP + { lpLine = 37 , lpColumn = 9 , lpStartByte = 600 , lpLength = 4 }) + LP + { lpLine = 37 , lpColumn = 9 , lpStartByte = 600 , lpLength = 4 } + ] + ) + LP + { lpLine = 37 , lpColumn = 1 , lpStartByte = 592 , lpLength = 13 }) + LP + { lpLine = 37 , lpColumn = 1 , lpStartByte = 592 , lpLength = 14 }) + LP + { lpLine = 37 , lpColumn = 1 , lpStartByte = 592 , lpLength = 14 } ] - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 606 } diff --git a/test/testcase/Batsh/if.ast b/test/testcase/Batsh/if.ast index a99e50f..52a5a23 100644 --- a/test/testcase/Batsh/if.ast +++ b/test/testcase/Batsh/if.ast @@ -2,135 +2,489 @@ Program [ Statement (If ( Binary - ( Less () , Literal (Int 2 ()) () , Literal (Int 10 ()) () ) () + ( Less + LP { lpLine = 1 , lpColumn = 7 , lpStartByte = 6 , lpLength = 1 } + , Literal + (Int + 2 + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 }) + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } + , Literal + (Int + 10 + LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 2 }) + LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 2 } + ) + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 6 } , Block [ Expression - (Call ( "println" , [ Literal (String "Yes" ()) () ] ) ()) () + (Call + ( "println" + , [ Literal + (String + "Yes" + LP + { lpLine = 2 , lpColumn = 11 , lpStartByte = 24 , lpLength = 5 }) + LP { lpLine = 2 , lpColumn = 11 , lpStartByte = 24 , lpLength = 5 } + ] + ) + LP + { lpLine = 2 , lpColumn = 3 , lpStartByte = 16 , lpLength = 14 }) + LP { lpLine = 2 , lpColumn = 3 , lpStartByte = 16 , lpLength = 15 } ] - () + LP + { lpLine = 1 , lpColumn = 13 , lpStartByte = 12 , lpLength = 21 } ) - ()) - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } , Statement (IfElse - ( Literal (Bool True ()) () + ( Literal + (Bool + True + LP { lpLine = 4 , lpColumn = 5 , lpStartByte = 38 , lpLength = 4 }) + LP { lpLine = 4 , lpColumn = 5 , lpStartByte = 38 , lpLength = 4 } , Block [ IfElse - ( Literal (Bool False ()) () + ( Literal + (Bool + False + LP { lpLine = 5 , lpColumn = 7 , lpStartByte = 52 , lpLength = 5 }) + LP { lpLine = 5 , lpColumn = 7 , lpStartByte = 52 , lpLength = 5 } , Block [ Expression (Assign - ( Identifier "v" () + ( Identifier + "v" + LP { lpLine = 6 , lpColumn = 5 , lpStartByte = 65 , lpLength = 1 } , Binary - ( Plus () , Literal (Int 4 ()) () , Literal (Int 1 ()) () ) () + ( Plus + LP + { lpLine = 6 + , lpColumn = 11 + , lpStartByte = 71 + , lpLength = 1 + } + , Literal + (Int + 4 + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 69 + , lpLength = 1 + }) + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 69 + , lpLength = 1 + } + , Literal + (Int + 1 + LP + { lpLine = 6 + , lpColumn = 13 + , lpStartByte = 73 + , lpLength = 1 + }) + LP + { lpLine = 6 + , lpColumn = 13 + , lpStartByte = 73 + , lpLength = 1 + } + ) + LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 69 , lpLength = 5 } ) - ()) - () + LP { lpLine = 6 , lpColumn = 5 , lpStartByte = 65 , lpLength = 9 }) + LP { lpLine = 6 , lpColumn = 5 , lpStartByte = 65 , lpLength = 10 } ] - () + LP + { lpLine = 5 , lpColumn = 14 , lpStartByte = 59 , lpLength = 20 } , Block [ Expression - (Assign ( Identifier "v" () , Literal (Int 2 ()) () ) ()) () + (Assign + ( Identifier + "v" + LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 91 , lpLength = 1 } + , Literal + (Int + 2 + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 95 + , lpLength = 1 + }) + LP { lpLine = 8 , lpColumn = 9 , lpStartByte = 95 , lpLength = 1 } + ) + LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 91 , lpLength = 5 }) + LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 91 , lpLength = 6 } ] - () + LP + { lpLine = 7 , lpColumn = 10 , lpStartByte = 85 , lpLength = 16 } ) - () + LP { lpLine = 5 , lpColumn = 3 , lpStartByte = 48 , lpLength = 53 } , If - ( Literal (Bool False ()) () + ( Literal + (Bool + False + LP + { lpLine = 10 , lpColumn = 7 , lpStartByte = 108 , lpLength = 5 }) + LP + { lpLine = 10 , lpColumn = 7 , lpStartByte = 108 , lpLength = 5 } , Expression - (Call ( "println" , [ Literal (String "no" ()) () ] ) ()) () + (Call + ( "println" + , [ Literal + (String + "no" + LP + { lpLine = 10 + , lpColumn = 22 + , lpStartByte = 123 + , lpLength = 4 + }) + LP + { lpLine = 10 , lpColumn = 22 , lpStartByte = 123 , lpLength = 4 } + ] + ) + LP + { lpLine = 10 + , lpColumn = 14 + , lpStartByte = 115 + , lpLength = 13 + }) + LP + { lpLine = 10 , lpColumn = 14 , lpStartByte = 115 , lpLength = 14 } ) - () + LP + { lpLine = 10 , lpColumn = 3 , lpStartByte = 104 , lpLength = 25 } ] - () - , Block [] () + LP + { lpLine = 4 , lpColumn = 11 , lpStartByte = 44 , lpLength = 87 } + , Block + [] + LP + { lpLine = 11 , lpColumn = 8 , lpStartByte = 137 , lpLength = 4 } ) - ()) - () + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 34 , lpLength = 107 }) + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 34 , lpLength = 107 } , Statement (Expression - (Call ( "println" , [ LeftValue (Identifier "v" ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ LeftValue + (Identifier + "v" + LP + { lpLine = 14 , lpColumn = 9 , lpStartByte = 150 , lpLength = 1 }) + LP + { lpLine = 14 , lpColumn = 9 , lpStartByte = 150 , lpLength = 1 } + ] + ) + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 142 , lpLength = 10 }) + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 142 , lpLength = 11 }) + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 142 , lpLength = 11 } , Statement (If ( Binary - ( Greater () , Literal (Int 2 ()) () , Literal (Int 1 ()) () ) () + ( Greater + LP + { lpLine = 15 , lpColumn = 7 , lpStartByte = 160 , lpLength = 1 } + , Literal + (Int + 2 + LP + { lpLine = 15 , lpColumn = 5 , lpStartByte = 158 , lpLength = 1 }) + LP + { lpLine = 15 , lpColumn = 5 , lpStartByte = 158 , lpLength = 1 } + , Literal + (Int + 1 + LP + { lpLine = 15 , lpColumn = 9 , lpStartByte = 162 , lpLength = 1 }) + LP + { lpLine = 15 , lpColumn = 9 , lpStartByte = 162 , lpLength = 1 } + ) + LP + { lpLine = 15 , lpColumn = 5 , lpStartByte = 158 , lpLength = 5 } , Expression - (Call ( "println" , [ Literal (String "True" ()) () ] ) ()) () + (Call + ( "println" + , [ Literal + (String + "True" + LP + { lpLine = 15 , lpColumn = 20 , lpStartByte = 173 , lpLength = 6 }) + LP + { lpLine = 15 , lpColumn = 20 , lpStartByte = 173 , lpLength = 6 } + ] + ) + LP + { lpLine = 15 + , lpColumn = 12 + , lpStartByte = 165 + , lpLength = 15 + }) + LP + { lpLine = 15 , lpColumn = 12 , lpStartByte = 165 , lpLength = 16 } ) - ()) - () + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 154 , lpLength = 27 }) + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 154 , lpLength = 27 } , Statement (If ( Binary - ( ArithEqual () , Literal (Int 1 ()) () , Literal (Int 12 ()) () ) - () + ( ArithEqual + LP + { lpLine = 16 , lpColumn = 7 , lpStartByte = 188 , lpLength = 3 } + , Literal + (Int + 1 + LP + { lpLine = 16 , lpColumn = 5 , lpStartByte = 186 , lpLength = 1 }) + LP + { lpLine = 16 , lpColumn = 5 , lpStartByte = 186 , lpLength = 1 } + , Literal + (Int + 12 + LP + { lpLine = 16 , lpColumn = 11 , lpStartByte = 192 , lpLength = 2 }) + LP + { lpLine = 16 , lpColumn = 11 , lpStartByte = 192 , lpLength = 2 } + ) + LP + { lpLine = 16 , lpColumn = 5 , lpStartByte = 186 , lpLength = 8 } , Block [ Expression - (Call ( "println" , [ Literal (String "No" ()) () ] ) ()) () + (Call + ( "println" + , [ Literal + (String + "No" + LP + { lpLine = 17 , lpColumn = 11 , lpStartByte = 208 , lpLength = 4 }) + LP + { lpLine = 17 , lpColumn = 11 , lpStartByte = 208 , lpLength = 4 } + ] + ) + LP + { lpLine = 17 , lpColumn = 3 , lpStartByte = 200 , lpLength = 13 }) + LP + { lpLine = 17 , lpColumn = 3 , lpStartByte = 200 , lpLength = 14 } ] - () + LP + { lpLine = 16 , lpColumn = 15 , lpStartByte = 196 , lpLength = 20 } ) - ()) - () + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 182 , lpLength = 34 }) + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 182 , lpLength = 34 } , Statement (IfElse ( Binary - ( Equal () - , Literal (String "a" ()) () - , Literal (String "b" ()) () + ( Equal + LP + { lpLine = 19 , lpColumn = 9 , lpStartByte = 225 , lpLength = 2 } + , Literal + (String + "a" + LP + { lpLine = 19 , lpColumn = 5 , lpStartByte = 221 , lpLength = 3 }) + LP + { lpLine = 19 , lpColumn = 5 , lpStartByte = 221 , lpLength = 3 } + , Literal + (String + "b" + LP + { lpLine = 19 , lpColumn = 12 , lpStartByte = 228 , lpLength = 3 }) + LP + { lpLine = 19 , lpColumn = 12 , lpStartByte = 228 , lpLength = 3 } ) - () + LP + { lpLine = 19 , lpColumn = 5 , lpStartByte = 221 , lpLength = 10 } , Block [ Expression - (Call ( "println" , [ Literal (String "No" ()) () ] ) ()) () + (Call + ( "println" + , [ Literal + (String + "No" + LP + { lpLine = 20 , lpColumn = 11 , lpStartByte = 245 , lpLength = 4 }) + LP + { lpLine = 20 , lpColumn = 11 , lpStartByte = 245 , lpLength = 4 } + ] + ) + LP + { lpLine = 20 , lpColumn = 3 , lpStartByte = 237 , lpLength = 13 }) + LP + { lpLine = 20 , lpColumn = 3 , lpStartByte = 237 , lpLength = 14 } ] - () + LP + { lpLine = 19 , lpColumn = 17 , lpStartByte = 233 , lpLength = 20 } , Block [ Expression - (Call ( "println" , [ Literal (String "a is not b" ()) () ] ) ()) - () + (Call + ( "println" + , [ Literal + (String + "a is not b" + LP + { lpLine = 22 + , lpColumn = 11 + , lpStartByte = 271 + , lpLength = 12 + }) + LP + { lpLine = 22 , lpColumn = 11 , lpStartByte = 271 , lpLength = 12 } + ] + ) + LP + { lpLine = 22 , lpColumn = 3 , lpStartByte = 263 , lpLength = 21 }) + LP + { lpLine = 22 , lpColumn = 3 , lpStartByte = 263 , lpLength = 22 } ] - () + LP + { lpLine = 21 , lpColumn = 8 , lpStartByte = 259 , lpLength = 28 } ) - ()) - () + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 217 , lpLength = 70 }) + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 217 , lpLength = 70 } , Statement (Expression - (Assign ( Identifier "num" () , Literal (Int 43 ()) () ) ()) ()) - () + (Assign + ( Identifier + "num" + LP + { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 3 } + , Literal + (Int + 43 + LP + { lpLine = 24 , lpColumn = 7 , lpStartByte = 294 , lpLength = 2 }) + LP + { lpLine = 24 , lpColumn = 7 , lpStartByte = 294 , lpLength = 2 } + ) + LP + { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 8 }) + LP + { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 9 }) + LP + { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 9 } , Statement (If ( Binary - ( Equal () - , Literal (String "43" ()) () - , LeftValue (Identifier "num" ()) () + ( Equal + LP + { lpLine = 25 , lpColumn = 10 , lpStartByte = 307 , lpLength = 2 } + , Literal + (String + "43" + LP + { lpLine = 25 , lpColumn = 5 , lpStartByte = 302 , lpLength = 4 }) + LP + { lpLine = 25 , lpColumn = 5 , lpStartByte = 302 , lpLength = 4 } + , LeftValue + (Identifier + "num" + LP + { lpLine = 25 , lpColumn = 13 , lpStartByte = 310 , lpLength = 3 }) + LP + { lpLine = 25 , lpColumn = 13 , lpStartByte = 310 , lpLength = 3 } ) - () + LP + { lpLine = 25 , lpColumn = 5 , lpStartByte = 302 , lpLength = 11 } , Block [ Expression - (Call ( "println" , [ Literal (String "43 == num" ()) () ] ) ()) () + (Call + ( "println" + , [ Literal + (String + "43 == num" + LP + { lpLine = 26 + , lpColumn = 11 + , lpStartByte = 327 + , lpLength = 11 + }) + LP + { lpLine = 26 , lpColumn = 11 , lpStartByte = 327 , lpLength = 11 } + ] + ) + LP + { lpLine = 26 , lpColumn = 3 , lpStartByte = 319 , lpLength = 20 }) + LP + { lpLine = 26 , lpColumn = 3 , lpStartByte = 319 , lpLength = 21 } ] - () + LP + { lpLine = 25 , lpColumn = 18 , lpStartByte = 315 , lpLength = 27 } ) - ()) - () + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 298 , lpLength = 44 }) + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 298 , lpLength = 44 } , Statement (If ( Binary - ( ArithEqual () - , Literal (String "43" ()) () - , LeftValue (Identifier "num" ()) () + ( ArithEqual + LP + { lpLine = 28 , lpColumn = 10 , lpStartByte = 352 , lpLength = 3 } + , Literal + (String + "43" + LP + { lpLine = 28 , lpColumn = 5 , lpStartByte = 347 , lpLength = 4 }) + LP + { lpLine = 28 , lpColumn = 5 , lpStartByte = 347 , lpLength = 4 } + , LeftValue + (Identifier + "num" + LP + { lpLine = 28 , lpColumn = 14 , lpStartByte = 356 , lpLength = 3 }) + LP + { lpLine = 28 , lpColumn = 14 , lpStartByte = 356 , lpLength = 3 } ) - () + LP + { lpLine = 28 , lpColumn = 5 , lpStartByte = 347 , lpLength = 12 } , Block [ Expression - (Call ( "println" , [ Literal (String "43 === num" ()) () ] ) ()) - () + (Call + ( "println" + , [ Literal + (String + "43 === num" + LP + { lpLine = 29 + , lpColumn = 11 + , lpStartByte = 373 + , lpLength = 12 + }) + LP + { lpLine = 29 , lpColumn = 11 , lpStartByte = 373 , lpLength = 12 } + ] + ) + LP + { lpLine = 29 , lpColumn = 3 , lpStartByte = 365 , lpLength = 21 }) + LP + { lpLine = 29 , lpColumn = 3 , lpStartByte = 365 , lpLength = 22 } ] - () + LP + { lpLine = 28 , lpColumn = 19 , lpStartByte = 361 , lpLength = 28 } ) - ()) - () + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 343 , lpLength = 46 }) + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 343 , lpLength = 46 } ] - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 389 } diff --git a/test/testcase/Batsh/recursion.ast b/test/testcase/Batsh/recursion.ast index c77c291..8b5ab74 100644 --- a/test/testcase/Batsh/recursion.ast +++ b/test/testcase/Batsh/recursion.ast @@ -1,183 +1,611 @@ Program - [ Statement (Comment " Loop" ()) () + [ Statement + (Comment + " Loop" + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 7 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 7 } , Function ( "loop" , [ "num" ] , [ Expression - (Call ( "println" , [ LeftValue (Identifier "num" ()) () ] ) ()) () + (Call + ( "println" + , [ LeftValue + (Identifier + "num" + LP + { lpLine = 3 , lpColumn = 11 , lpStartByte = 39 , lpLength = 3 }) + LP { lpLine = 3 , lpColumn = 11 , lpStartByte = 39 , lpLength = 3 } + ] + ) + LP + { lpLine = 3 , lpColumn = 3 , lpStartByte = 31 , lpLength = 12 }) + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 31 , lpLength = 13 } , If ( Binary - ( Greater () - , LeftValue (Identifier "num" ()) () - , Literal (Int 0 ()) () + ( Greater + LP { lpLine = 4 , lpColumn = 11 , lpStartByte = 55 , lpLength = 1 } + , LeftValue + (Identifier + "num" + LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 51 , lpLength = 3 }) + LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 51 , lpLength = 3 } + , Literal + (Int + 0 + LP + { lpLine = 4 , lpColumn = 13 , lpStartByte = 57 , lpLength = 1 }) + LP { lpLine = 4 , lpColumn = 13 , lpStartByte = 57 , lpLength = 1 } ) - () + LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 51 , lpLength = 7 } , Block [ Expression (Call ( "loop" , [ Binary - ( Minus () - , LeftValue (Identifier "num" ()) () - , Literal (Int 1 ()) () + ( Minus + LP { lpLine = 5 , lpColumn = 14 , lpStartByte = 75 , lpLength = 1 } + , LeftValue + (Identifier + "num" + LP + { lpLine = 5 + , lpColumn = 10 + , lpStartByte = 71 + , lpLength = 3 + }) + LP { lpLine = 5 , lpColumn = 10 , lpStartByte = 71 , lpLength = 3 } + , Literal + (Int + 1 + LP + { lpLine = 5 + , lpColumn = 16 + , lpStartByte = 77 + , lpLength = 1 + }) + LP { lpLine = 5 , lpColumn = 16 , lpStartByte = 77 , lpLength = 1 } ) - () + LP { lpLine = 5 , lpColumn = 10 , lpStartByte = 71 , lpLength = 7 } ] ) - ()) - () + LP + { lpLine = 5 , lpColumn = 5 , lpStartByte = 66 , lpLength = 13 }) + LP { lpLine = 5 , lpColumn = 5 , lpStartByte = 66 , lpLength = 14 } ] - () + LP + { lpLine = 4 , lpColumn = 16 , lpStartByte = 60 , lpLength = 24 } ) - () + LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 47 , lpLength = 37 } ] ) - () + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 8 , lpLength = 78 } , Statement - (Expression (Call ( "loop" , [ Literal (Int 10 ()) () ] ) ()) ()) - () - , Statement (Comment " Factorial" ()) () + (Expression + (Call + ( "loop" + , [ Literal + (Int + 10 + LP { lpLine = 8 , lpColumn = 6 , lpStartByte = 92 , lpLength = 2 }) + LP { lpLine = 8 , lpColumn = 6 , lpStartByte = 92 , lpLength = 2 } + ] + ) + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 87 , lpLength = 8 }) + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 87 , lpLength = 9 }) + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 87 , lpLength = 9 } + , Statement + (Comment + " Factorial" + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 97 , lpLength = 12 }) + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 97 , lpLength = 12 } , Function ( "fact" , [ "num" ] , [ IfElse ( Binary - ( ArithEqual () - , LeftValue (Identifier "num" ()) () - , Literal (Int 0 ()) () + ( ArithEqual + LP + { lpLine = 11 , lpColumn = 11 , lpStartByte = 141 , lpLength = 3 } + , LeftValue + (Identifier + "num" + LP + { lpLine = 11 , lpColumn = 7 , lpStartByte = 137 , lpLength = 3 }) + LP + { lpLine = 11 , lpColumn = 7 , lpStartByte = 137 , lpLength = 3 } + , Literal + (Int + 0 + LP + { lpLine = 11 , lpColumn = 15 , lpStartByte = 145 , lpLength = 1 }) + LP + { lpLine = 11 , lpColumn = 15 , lpStartByte = 145 , lpLength = 1 } ) - () - , Block [ Return (Just (Literal (Int 1 ()) ())) () ] () + LP + { lpLine = 11 , lpColumn = 7 , lpStartByte = 137 , lpLength = 9 } + , Block + [ Return + (Just + (Literal + (Int + 1 + LP + { lpLine = 12 , lpColumn = 12 , lpStartByte = 161 , lpLength = 1 }) + LP + { lpLine = 12 + , lpColumn = 12 + , lpStartByte = 161 + , lpLength = 1 + })) + LP + { lpLine = 12 , lpColumn = 5 , lpStartByte = 154 , lpLength = 9 } + ] + LP + { lpLine = 11 , lpColumn = 18 , lpStartByte = 148 , lpLength = 19 } , Block [ Return (Just (Binary - ( Multiply () + ( Multiply + LP + { lpLine = 14 , lpColumn = 26 , lpStartByte = 200 , lpLength = 1 } , Call ( "fact" , [ Binary - ( Minus () - , LeftValue (Identifier "num" ()) () - , Literal (Int 1 ()) () + ( Minus + LP + { lpLine = 14 + , lpColumn = 21 + , lpStartByte = 195 + , lpLength = 1 + } + , LeftValue + (Identifier + "num" + LP + { lpLine = 14 + , lpColumn = 17 + , lpStartByte = 191 + , lpLength = 3 + }) + LP + { lpLine = 14 + , lpColumn = 17 + , lpStartByte = 191 + , lpLength = 3 + } + , Literal + (Int + 1 + LP + { lpLine = 14 + , lpColumn = 23 + , lpStartByte = 197 + , lpLength = 1 + }) + LP + { lpLine = 14 + , lpColumn = 23 + , lpStartByte = 197 + , lpLength = 1 + } ) - () + LP + { lpLine = 14 + , lpColumn = 17 + , lpStartByte = 191 + , lpLength = 7 + } ] ) - () - , LeftValue (Identifier "num" ()) () + LP + { lpLine = 14 , lpColumn = 12 , lpStartByte = 186 , lpLength = 13 } + , LeftValue + (Identifier + "num" + LP + { lpLine = 14 + , lpColumn = 28 + , lpStartByte = 202 + , lpLength = 3 + }) + LP + { lpLine = 14 , lpColumn = 28 , lpStartByte = 202 , lpLength = 3 } ) - ())) - () + LP + { lpLine = 14 + , lpColumn = 12 + , lpStartByte = 186 + , lpLength = 19 + })) + LP + { lpLine = 14 , lpColumn = 5 , lpStartByte = 179 , lpLength = 27 } ] - () + LP + { lpLine = 13 , lpColumn = 10 , lpStartByte = 173 , lpLength = 37 } ) - () + LP + { lpLine = 11 , lpColumn = 3 , lpStartByte = 133 , lpLength = 77 } ] ) - () + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 110 , lpLength = 102 } , Statement (Expression (Call - ( "println" , [ Call ( "fact" , [ Literal (Int 5 ()) () ] ) () ] ) - ()) - ()) - () - , Statement (Comment " Fibonacci" ()) () + ( "println" + , [ Call + ( "fact" + , [ Literal + (Int + 5 + LP + { lpLine = 17 , lpColumn = 14 , lpStartByte = 226 , lpLength = 1 }) + LP + { lpLine = 17 , lpColumn = 14 , lpStartByte = 226 , lpLength = 1 } + ] + ) + LP + { lpLine = 17 , lpColumn = 9 , lpStartByte = 221 , lpLength = 7 } + ] + ) + LP + { lpLine = 17 , lpColumn = 1 , lpStartByte = 213 , lpLength = 16 }) + LP + { lpLine = 17 , lpColumn = 1 , lpStartByte = 213 , lpLength = 17 }) + LP + { lpLine = 17 , lpColumn = 1 , lpStartByte = 213 , lpLength = 17 } + , Statement + (Comment + " Fibonacci" + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 231 , lpLength = 12 }) + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 231 , lpLength = 12 } , Function ( "fibonacci" , [ "num" ] , [ IfElse ( Binary - ( ArithEqual () - , LeftValue (Identifier "num" ()) () - , Literal (Int 0 ()) () + ( ArithEqual + LP + { lpLine = 20 , lpColumn = 11 , lpStartByte = 280 , lpLength = 3 } + , LeftValue + (Identifier + "num" + LP + { lpLine = 20 , lpColumn = 7 , lpStartByte = 276 , lpLength = 3 }) + LP + { lpLine = 20 , lpColumn = 7 , lpStartByte = 276 , lpLength = 3 } + , Literal + (Int + 0 + LP + { lpLine = 20 , lpColumn = 15 , lpStartByte = 284 , lpLength = 1 }) + LP + { lpLine = 20 , lpColumn = 15 , lpStartByte = 284 , lpLength = 1 } ) - () - , Block [ Return (Just (Literal (Int 0 ()) ())) () ] () + LP + { lpLine = 20 , lpColumn = 7 , lpStartByte = 276 , lpLength = 9 } + , Block + [ Return + (Just + (Literal + (Int + 0 + LP + { lpLine = 21 , lpColumn = 12 , lpStartByte = 300 , lpLength = 1 }) + LP + { lpLine = 21 + , lpColumn = 12 + , lpStartByte = 300 + , lpLength = 1 + })) + LP + { lpLine = 21 , lpColumn = 5 , lpStartByte = 293 , lpLength = 9 } + ] + LP + { lpLine = 20 , lpColumn = 18 , lpStartByte = 287 , lpLength = 19 } , IfElse ( Binary - ( ArithEqual () - , LeftValue (Identifier "num" ()) () - , Literal (Int 1 ()) () + ( ArithEqual + LP + { lpLine = 22 , lpColumn = 18 , lpStartByte = 320 , lpLength = 3 } + , LeftValue + (Identifier + "num" + LP + { lpLine = 22 , lpColumn = 14 , lpStartByte = 316 , lpLength = 3 }) + LP + { lpLine = 22 , lpColumn = 14 , lpStartByte = 316 , lpLength = 3 } + , Literal + (Int + 1 + LP + { lpLine = 22 , lpColumn = 22 , lpStartByte = 324 , lpLength = 1 }) + LP + { lpLine = 22 , lpColumn = 22 , lpStartByte = 324 , lpLength = 1 } ) - () - , Block [ Return (Just (Literal (Int 1 ()) ())) () ] () + LP + { lpLine = 22 , lpColumn = 14 , lpStartByte = 316 , lpLength = 9 } + , Block + [ Return + (Just + (Literal + (Int + 1 + LP + { lpLine = 23 + , lpColumn = 12 + , lpStartByte = 340 + , lpLength = 1 + }) + LP + { lpLine = 23 + , lpColumn = 12 + , lpStartByte = 340 + , lpLength = 1 + })) + LP + { lpLine = 23 , lpColumn = 5 , lpStartByte = 333 , lpLength = 9 } + ] + LP + { lpLine = 22 , lpColumn = 25 , lpStartByte = 327 , lpLength = 19 } , Block [ Return (Just (Binary - ( Plus () + ( Plus + LP + { lpLine = 25 + , lpColumn = 31 + , lpStartByte = 384 + , lpLength = 1 + } , Call ( "fibonacci" , [ Binary - ( Minus () - , LeftValue (Identifier "num" ()) () - , Literal (Int 2 ()) () + ( Minus + LP + { lpLine = 25 + , lpColumn = 26 + , lpStartByte = 379 + , lpLength = 1 + } + , LeftValue + (Identifier + "num" + LP + { lpLine = 25 + , lpColumn = 22 + , lpStartByte = 375 + , lpLength = 3 + }) + LP + { lpLine = 25 + , lpColumn = 22 + , lpStartByte = 375 + , lpLength = 3 + } + , Literal + (Int + 2 + LP + { lpLine = 25 + , lpColumn = 28 + , lpStartByte = 381 + , lpLength = 1 + }) + LP + { lpLine = 25 + , lpColumn = 28 + , lpStartByte = 381 + , lpLength = 1 + } ) - () + LP + { lpLine = 25 + , lpColumn = 22 + , lpStartByte = 375 + , lpLength = 7 + } ] ) - () + LP + { lpLine = 25 + , lpColumn = 12 + , lpStartByte = 365 + , lpLength = 18 + } , Call ( "fibonacci" , [ Binary - ( Minus () - , LeftValue (Identifier "num" ()) () - , Literal (Int 1 ()) () + ( Minus + LP + { lpLine = 25 + , lpColumn = 47 + , lpStartByte = 400 + , lpLength = 1 + } + , LeftValue + (Identifier + "num" + LP + { lpLine = 25 + , lpColumn = 43 + , lpStartByte = 396 + , lpLength = 3 + }) + LP + { lpLine = 25 + , lpColumn = 43 + , lpStartByte = 396 + , lpLength = 3 + } + , Literal + (Int + 1 + LP + { lpLine = 25 + , lpColumn = 49 + , lpStartByte = 402 + , lpLength = 1 + }) + LP + { lpLine = 25 + , lpColumn = 49 + , lpStartByte = 402 + , lpLength = 1 + } ) - () + LP + { lpLine = 25 + , lpColumn = 43 + , lpStartByte = 396 + , lpLength = 7 + } ] ) - () + LP + { lpLine = 25 + , lpColumn = 33 + , lpStartByte = 386 + , lpLength = 18 + } ) - ())) - () + LP + { lpLine = 25 + , lpColumn = 12 + , lpStartByte = 365 + , lpLength = 39 + })) + LP + { lpLine = 25 , lpColumn = 5 , lpStartByte = 358 , lpLength = 47 } ] - () + LP + { lpLine = 24 , lpColumn = 10 , lpStartByte = 352 , lpLength = 57 } ) - () + LP + { lpLine = 22 , lpColumn = 10 , lpStartByte = 312 , lpLength = 97 } ) - () + LP + { lpLine = 20 , lpColumn = 3 , lpStartByte = 272 , lpLength = 137 } ] ) - () + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 244 , lpLength = 167 } , Statement (Expression - (Assign ( Identifier "i" () , Literal (Int 0 ()) () ) ()) ()) - () + (Assign + ( Identifier + "i" + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 1 } + , Literal + (Int + 0 + LP + { lpLine = 28 , lpColumn = 5 , lpStartByte = 416 , lpLength = 1 }) + LP + { lpLine = 28 , lpColumn = 5 , lpStartByte = 416 , lpLength = 1 } + ) + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 5 }) + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 6 }) + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 6 } , Statement (While ( Binary - ( Less () - , LeftValue (Identifier "i" ()) () - , Literal (Int 7 ()) () + ( Less + LP + { lpLine = 29 , lpColumn = 10 , lpStartByte = 428 , lpLength = 1 } + , LeftValue + (Identifier + "i" + LP + { lpLine = 29 , lpColumn = 8 , lpStartByte = 426 , lpLength = 1 }) + LP + { lpLine = 29 , lpColumn = 8 , lpStartByte = 426 , lpLength = 1 } + , Literal + (Int + 7 + LP + { lpLine = 29 , lpColumn = 12 , lpStartByte = 430 , lpLength = 1 }) + LP + { lpLine = 29 , lpColumn = 12 , lpStartByte = 430 , lpLength = 1 } ) - () + LP + { lpLine = 29 , lpColumn = 8 , lpStartByte = 426 , lpLength = 5 } , Block [ Expression (Call ( "println" - , [ Call ( "fibonacci" , [ LeftValue (Identifier "i" ()) () ] ) () + , [ Call + ( "fibonacci" + , [ LeftValue + (Identifier + "i" + LP + { lpLine = 30 + , lpColumn = 21 + , lpStartByte = 455 + , lpLength = 1 + }) + LP + { lpLine = 30 , lpColumn = 21 , lpStartByte = 455 , lpLength = 1 } + ] + ) + LP + { lpLine = 30 , lpColumn = 11 , lpStartByte = 445 , lpLength = 12 } ] ) - ()) - () + LP + { lpLine = 30 , lpColumn = 3 , lpStartByte = 437 , lpLength = 21 }) + LP + { lpLine = 30 , lpColumn = 3 , lpStartByte = 437 , lpLength = 22 } , Expression (Assign - ( Identifier "i" () + ( Identifier + "i" + LP + { lpLine = 31 , lpColumn = 3 , lpStartByte = 462 , lpLength = 1 } , Binary - ( Plus () - , LeftValue (Identifier "i" ()) () - , Literal (Int 1 ()) () + ( Plus + LP + { lpLine = 31 , lpColumn = 9 , lpStartByte = 468 , lpLength = 1 } + , LeftValue + (Identifier + "i" + LP + { lpLine = 31 , lpColumn = 7 , lpStartByte = 466 , lpLength = 1 }) + LP + { lpLine = 31 , lpColumn = 7 , lpStartByte = 466 , lpLength = 1 } + , Literal + (Int + 1 + LP + { lpLine = 31 , lpColumn = 11 , lpStartByte = 470 , lpLength = 1 }) + LP + { lpLine = 31 , lpColumn = 11 , lpStartByte = 470 , lpLength = 1 } ) - () + LP + { lpLine = 31 , lpColumn = 7 , lpStartByte = 466 , lpLength = 5 } ) - ()) - () + LP + { lpLine = 31 , lpColumn = 3 , lpStartByte = 462 , lpLength = 9 }) + LP + { lpLine = 31 , lpColumn = 3 , lpStartByte = 462 , lpLength = 10 } ] - () + LP + { lpLine = 29 , lpColumn = 15 , lpStartByte = 433 , lpLength = 41 } ) - ()) - () + LP + { lpLine = 29 , lpColumn = 1 , lpStartByte = 419 , lpLength = 55 }) + LP + { lpLine = 29 , lpColumn = 1 , lpStartByte = 419 , lpLength = 55 } ] - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 474 } diff --git a/test/testcase/Batsh/string.ast b/test/testcase/Batsh/string.ast index 7f53a88..ee97cf0 100644 --- a/test/testcase/Batsh/string.ast +++ b/test/testcase/Batsh/string.ast @@ -1,138 +1,399 @@ Program [ Statement (Expression - (Call ( "println" , [ Literal (String "BYVoid" ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ Literal + (String + "BYVoid" + LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 8 }) + LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 8 } + ] + ) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 17 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 18 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 18 } , Statement (Expression - (Call ( "println" , [ Literal (String "Slash/" ()) () ] ) ()) ()) - () + (Call + ( "println" + , [ Literal + (String + "Slash/" + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 27 , lpLength = 8 }) + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 27 , lpLength = 8 } + ] + ) + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 19 , lpLength = 17 }) + LP + { lpLine = 2 , lpColumn = 1 , lpStartByte = 19 , lpLength = 18 }) + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 19 , lpLength = 18 } , Statement (Expression (Call - ( "println" , [ Literal (String "Backslash\\\\" ()) () ] ) ()) - ()) - () + ( "println" + , [ Literal + (String + "Backslash\\\\" + LP + { lpLine = 3 , lpColumn = 9 , lpStartByte = 46 , lpLength = 13 }) + LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 46 , lpLength = 13 } + ] + ) + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 22 }) + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 23 }) + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 23 } , Statement (Expression - (Call ( "println" , [ Literal (String "Quote\\\"'" ()) () ] ) ()) - ()) - () + (Call + ( "println" + , [ Literal + (String + "Quote\\\"'" + LP + { lpLine = 4 , lpColumn = 9 , lpStartByte = 70 , lpLength = 10 }) + LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 70 , lpLength = 10 } + ] + ) + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 62 , lpLength = 19 }) + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 62 , lpLength = 20 }) + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 62 , lpLength = 20 } , Statement (Expression - (Call ( "println" , [ Literal (String "Tab\\tTab" ()) () ] ) ()) - ()) - () - , Statement (Comment "println(\"Newline\\nLine2\");" ()) () - , Statement (Comment "println(\"!\");" ()) () + (Call + ( "println" + , [ Literal + (String + "Tab\\tTab" + LP + { lpLine = 5 , lpColumn = 9 , lpStartByte = 91 , lpLength = 10 }) + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 91 , lpLength = 10 } + ] + ) + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 83 , lpLength = 19 }) + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 83 , lpLength = 20 }) + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 83 , lpLength = 20 } + , Statement + (Comment + "println(\"Newline\\nLine2\");" + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 104 , lpLength = 28 }) + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 104 , lpLength = 28 } + , Statement + (Comment + "println(\"!\");" + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 133 , lpLength = 15 }) + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 133 , lpLength = 15 } , Statement (Expression (Call ( "println" , [ Binary - ( Concat () + ( Concat + LP + { lpLine = 8 , lpColumn = 41 , lpStartByte = 189 , lpLength = 2 } , Binary - ( Concat () + ( Concat + LP + { lpLine = 8 , lpColumn = 29 , lpStartByte = 177 , lpLength = 2 } , Binary - ( Concat () - , Literal (String "http://" ()) () - , Literal (String "www." ()) () + ( Concat + LP + { lpLine = 8 , lpColumn = 19 , lpStartByte = 167 , lpLength = 2 } + , Literal + (String + "http://" + LP + { lpLine = 8 , lpColumn = 9 , lpStartByte = 157 , lpLength = 9 }) + LP { lpLine = 8 , lpColumn = 9 , lpStartByte = 157 , lpLength = 9 } + , Literal + (String + "www." + LP + { lpLine = 8 + , lpColumn = 22 + , lpStartByte = 170 + , lpLength = 6 + }) + LP + { lpLine = 8 , lpColumn = 22 , lpStartByte = 170 , lpLength = 6 } ) - () - , Literal (String "byvoid" ()) () + LP + { lpLine = 8 , lpColumn = 9 , lpStartByte = 157 , lpLength = 19 } + , Literal + (String + "byvoid" + LP + { lpLine = 8 , lpColumn = 32 , lpStartByte = 180 , lpLength = 8 }) + LP + { lpLine = 8 , lpColumn = 32 , lpStartByte = 180 , lpLength = 8 } ) - () - , Literal (String ".com" ()) () + LP + { lpLine = 8 , lpColumn = 9 , lpStartByte = 157 , lpLength = 31 } + , Literal + (String + ".com" + LP + { lpLine = 8 , lpColumn = 44 , lpStartByte = 192 , lpLength = 6 }) + LP + { lpLine = 8 , lpColumn = 44 , lpStartByte = 192 , lpLength = 6 } ) - () + LP + { lpLine = 8 , lpColumn = 9 , lpStartByte = 157 , lpLength = 41 } ] ) - ()) - ()) - () + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 149 , lpLength = 50 }) + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 149 , lpLength = 51 }) + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 149 , lpLength = 51 } , Statement (Expression (Call ( "println" , [ Binary - ( Concat () + ( Concat + LP + { lpLine = 9 , lpColumn = 27 , lpStartByte = 227 , lpLength = 2 } , Binary - ( Concat () + ( Concat + LP + { lpLine = 9 , lpColumn = 15 , lpStartByte = 215 , lpLength = 2 } , Binary - ( Divide () , Literal (Int 6 ()) () , Literal (Int 2 ()) () ) () - , Literal (String "BYVoid" ()) () + ( Divide + LP + { lpLine = 9 , lpColumn = 11 , lpStartByte = 211 , lpLength = 1 } + , Literal + (Int + 6 + LP + { lpLine = 9 , lpColumn = 9 , lpStartByte = 209 , lpLength = 1 }) + LP { lpLine = 9 , lpColumn = 9 , lpStartByte = 209 , lpLength = 1 } + , Literal + (Int + 2 + LP + { lpLine = 9 + , lpColumn = 13 + , lpStartByte = 213 + , lpLength = 1 + }) + LP + { lpLine = 9 , lpColumn = 13 , lpStartByte = 213 , lpLength = 1 } + ) + LP { lpLine = 9 , lpColumn = 9 , lpStartByte = 209 , lpLength = 5 } + , Literal + (String + "BYVoid" + LP + { lpLine = 9 , lpColumn = 18 , lpStartByte = 218 , lpLength = 8 }) + LP + { lpLine = 9 , lpColumn = 18 , lpStartByte = 218 , lpLength = 8 } ) - () + LP + { lpLine = 9 , lpColumn = 9 , lpStartByte = 209 , lpLength = 17 } , Binary - ( Plus () , Literal (Int 3 ()) () , Literal (Int 5 ()) () ) () + ( Plus + LP + { lpLine = 9 , lpColumn = 32 , lpStartByte = 232 , lpLength = 1 } + , Literal + (Int + 3 + LP + { lpLine = 9 , lpColumn = 30 , lpStartByte = 230 , lpLength = 1 }) + LP + { lpLine = 9 , lpColumn = 30 , lpStartByte = 230 , lpLength = 1 } + , Literal + (Int + 5 + LP + { lpLine = 9 , lpColumn = 34 , lpStartByte = 234 , lpLength = 1 }) + LP + { lpLine = 9 , lpColumn = 34 , lpStartByte = 234 , lpLength = 1 } + ) + LP + { lpLine = 9 , lpColumn = 30 , lpStartByte = 230 , lpLength = 5 } ) - () + LP + { lpLine = 9 , lpColumn = 9 , lpStartByte = 209 , lpLength = 26 } ] ) - ()) - ()) - () + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 201 , lpLength = 35 }) + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 201 , lpLength = 36 }) + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 201 , lpLength = 36 } , Statement (Expression (Call ( "println" , [ Binary - ( Plus () , Literal (Int 3 ()) () , Literal (String "3" ()) () ) () + ( Plus + LP + { lpLine = 10 , lpColumn = 11 , lpStartByte = 248 , lpLength = 1 } + , Literal + (Int + 3 + LP + { lpLine = 10 , lpColumn = 9 , lpStartByte = 246 , lpLength = 1 }) + LP + { lpLine = 10 , lpColumn = 9 , lpStartByte = 246 , lpLength = 1 } + , Literal + (String + "3" + LP + { lpLine = 10 , lpColumn = 13 , lpStartByte = 250 , lpLength = 3 }) + LP + { lpLine = 10 , lpColumn = 13 , lpStartByte = 250 , lpLength = 3 } + ) + LP + { lpLine = 10 , lpColumn = 9 , lpStartByte = 246 , lpLength = 7 } ] ) - ()) - ()) - () + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 238 , lpLength = 16 }) + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 238 , lpLength = 17 }) + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 238 , lpLength = 17 } , Statement (Expression (Call ( "println" , [ Binary - ( Concat () + ( Concat + LP + { lpLine = 11 , lpColumn = 17 , lpStartByte = 272 , lpLength = 2 } , Binary - ( Plus () , Literal (Int 3 ()) () , Literal (String "3" ()) () ) () - , Literal (String "2" ()) () + ( Plus + LP + { lpLine = 11 , lpColumn = 11 , lpStartByte = 266 , lpLength = 1 } + , Literal + (Int + 3 + LP + { lpLine = 11 , lpColumn = 9 , lpStartByte = 264 , lpLength = 1 }) + LP + { lpLine = 11 , lpColumn = 9 , lpStartByte = 264 , lpLength = 1 } + , Literal + (String + "3" + LP + { lpLine = 11 , lpColumn = 13 , lpStartByte = 268 , lpLength = 3 }) + LP + { lpLine = 11 , lpColumn = 13 , lpStartByte = 268 , lpLength = 3 } + ) + LP + { lpLine = 11 , lpColumn = 9 , lpStartByte = 264 , lpLength = 7 } + , Literal + (String + "2" + LP + { lpLine = 11 , lpColumn = 20 , lpStartByte = 275 , lpLength = 3 }) + LP + { lpLine = 11 , lpColumn = 20 , lpStartByte = 275 , lpLength = 3 } ) - () + LP + { lpLine = 11 , lpColumn = 9 , lpStartByte = 264 , lpLength = 14 } ] ) - ()) - ()) - () + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 256 , lpLength = 23 }) + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 256 , lpLength = 24 }) + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 256 , lpLength = 24 } , Statement (Expression (Call ( "println" , [ Binary - ( Plus () - , Literal (Int 3 ()) () + ( Plus + LP + { lpLine = 12 , lpColumn = 11 , lpStartByte = 291 , lpLength = 1 } + , Literal + (Int + 3 + LP + { lpLine = 12 , lpColumn = 9 , lpStartByte = 289 , lpLength = 1 }) + LP + { lpLine = 12 , lpColumn = 9 , lpStartByte = 289 , lpLength = 1 } , Binary - ( Concat () - , Literal (String "3" ()) () - , Literal (String "2" ()) () + ( Concat + LP + { lpLine = 12 , lpColumn = 18 , lpStartByte = 298 , lpLength = 2 } + , Literal + (String + "3" + LP + { lpLine = 12 , lpColumn = 14 , lpStartByte = 294 , lpLength = 3 }) + LP + { lpLine = 12 , lpColumn = 14 , lpStartByte = 294 , lpLength = 3 } + , Literal + (String + "2" + LP + { lpLine = 12 , lpColumn = 21 , lpStartByte = 301 , lpLength = 3 }) + LP + { lpLine = 12 , lpColumn = 21 , lpStartByte = 301 , lpLength = 3 } ) - () + LP + { lpLine = 12 , lpColumn = 14 , lpStartByte = 294 , lpLength = 10 } ) - () + LP + { lpLine = 12 , lpColumn = 9 , lpStartByte = 289 , lpLength = 15 } ] ) - ()) - ()) - () + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 281 , lpLength = 25 }) + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 281 , lpLength = 26 }) + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 281 , lpLength = 26 } , Statement (Expression (Call ( "println" , [ Binary - ( Equal () - , Literal (String "BYVoid" ()) () - , Literal (String "BYVoid" ()) () + ( Equal + LP + { lpLine = 13 , lpColumn = 18 , lpStartByte = 325 , lpLength = 2 } + , Literal + (String + "BYVoid" + LP + { lpLine = 13 , lpColumn = 9 , lpStartByte = 316 , lpLength = 8 }) + LP + { lpLine = 13 , lpColumn = 9 , lpStartByte = 316 , lpLength = 8 } + , Literal + (String + "BYVoid" + LP + { lpLine = 13 , lpColumn = 21 , lpStartByte = 328 , lpLength = 8 }) + LP + { lpLine = 13 , lpColumn = 21 , lpStartByte = 328 , lpLength = 8 } ) - () + LP + { lpLine = 13 , lpColumn = 9 , lpStartByte = 316 , lpLength = 20 } ] ) - ()) - ()) - () + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 308 , lpLength = 29 }) + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 308 , lpLength = 30 }) + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 308 , lpLength = 30 } ] - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 338 } diff --git a/test/testcase/Batsh/while.ast b/test/testcase/Batsh/while.ast index 4a90311..0aea8b8 100644 --- a/test/testcase/Batsh/while.ast +++ b/test/testcase/Batsh/while.ast @@ -1,108 +1,301 @@ Program [ Statement (Expression - (Assign ( Identifier "i" () , Literal (Int 0 ()) () ) ()) ()) - () + (Assign + ( Identifier + "i" + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } + , Literal + (Int + 0 + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 }) + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } + ) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 5 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 }) + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 } , Statement (While ( Binary - ( Less () - , LeftValue (Identifier "i" ()) () - , Literal (Int 5 ()) () + ( Less + LP { lpLine = 2 , lpColumn = 10 , lpStartByte = 16 , lpLength = 1 } + , LeftValue + (Identifier + "i" + LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 14 , lpLength = 1 }) + LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 14 , lpLength = 1 } + , Literal + (Int + 5 + LP + { lpLine = 2 , lpColumn = 12 , lpStartByte = 18 , lpLength = 1 }) + LP { lpLine = 2 , lpColumn = 12 , lpStartByte = 18 , lpLength = 1 } ) - () + LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 14 , lpLength = 5 } , Block [ Expression (Call ( "print" , [ Binary - ( Concat () - , LeftValue (Identifier "i" ()) () - , Literal (String " " ()) () + ( Concat + LP { lpLine = 3 , lpColumn = 11 , lpStartByte = 33 , lpLength = 2 } + , LeftValue + (Identifier + "i" + LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 31 , lpLength = 1 }) + LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 31 , lpLength = 1 } + , Literal + (String + " " + LP + { lpLine = 3 , lpColumn = 14 , lpStartByte = 36 , lpLength = 3 }) + LP { lpLine = 3 , lpColumn = 14 , lpStartByte = 36 , lpLength = 3 } ) - () + LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 31 , lpLength = 8 } ] ) - ()) - () + LP + { lpLine = 3 , lpColumn = 3 , lpStartByte = 25 , lpLength = 15 }) + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 25 , lpLength = 16 } , Expression (Assign - ( Identifier "i" () + ( Identifier + "i" + LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 44 , lpLength = 1 } , Binary - ( Plus () - , LeftValue (Identifier "i" ()) () - , Literal (Int 1 ()) () + ( Plus + LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 50 , lpLength = 1 } + , LeftValue + (Identifier + "i" + LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 48 , lpLength = 1 }) + LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 48 , lpLength = 1 } + , Literal + (Int + 1 + LP + { lpLine = 4 , lpColumn = 11 , lpStartByte = 52 , lpLength = 1 }) + LP { lpLine = 4 , lpColumn = 11 , lpStartByte = 52 , lpLength = 1 } ) - () + LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 48 , lpLength = 5 } ) - ()) - () + LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 44 , lpLength = 9 }) + LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 44 , lpLength = 10 } ] - () + LP + { lpLine = 2 , lpColumn = 15 , lpStartByte = 21 , lpLength = 35 } ) - ()) - () - , Statement (Expression (Call ( "println" , [] ) ()) ()) () - , Statement (Comment " Fibonacci" ()) () + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 49 }) + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 49 } , Statement (Expression - (Assign ( Identifier "n" () , Literal (Int 0 ()) () ) ()) ()) - () + (Call + ( "println" , [] ) + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 57 , lpLength = 9 }) + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 57 , lpLength = 10 }) + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 57 , lpLength = 10 } + , Statement + (Comment + " Fibonacci" + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 68 , lpLength = 12 }) + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 68 , lpLength = 12 } + , Statement + (Expression + (Assign + ( Identifier + "n" + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 1 } + , Literal + (Int + 0 + LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 85 , lpLength = 1 }) + LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 85 , lpLength = 1 } + ) + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 5 }) + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 6 }) + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 6 } , Statement (Expression - (Assign ( Identifier "i" () , Literal (Int 0 ()) () ) ()) ()) - () + (Assign + ( Identifier + "i" + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 1 } + , Literal + (Int + 0 + LP { lpLine = 9 , lpColumn = 5 , lpStartByte = 92 , lpLength = 1 }) + LP { lpLine = 9 , lpColumn = 5 , lpStartByte = 92 , lpLength = 1 } + ) + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 5 }) + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 6 }) + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 6 } , Statement (Expression - (Assign ( Identifier "j" () , Literal (Int 1 ()) () ) ()) ()) - () + (Assign + ( Identifier + "j" + LP { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 1 } + , Literal + (Int + 1 + LP + { lpLine = 10 , lpColumn = 5 , lpStartByte = 99 , lpLength = 1 }) + LP { lpLine = 10 , lpColumn = 5 , lpStartByte = 99 , lpLength = 1 } + ) + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 5 }) + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 6 }) + LP { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 6 } , Statement (While ( Binary - ( Less () - , LeftValue (Identifier "n" ()) () - , Literal (Int 40 ()) () + ( Less + LP + { lpLine = 11 , lpColumn = 10 , lpStartByte = 111 , lpLength = 1 } + , LeftValue + (Identifier + "n" + LP + { lpLine = 11 , lpColumn = 8 , lpStartByte = 109 , lpLength = 1 }) + LP + { lpLine = 11 , lpColumn = 8 , lpStartByte = 109 , lpLength = 1 } + , Literal + (Int + 40 + LP + { lpLine = 11 , lpColumn = 12 , lpStartByte = 113 , lpLength = 2 }) + LP + { lpLine = 11 , lpColumn = 12 , lpStartByte = 113 , lpLength = 2 } ) - () + LP + { lpLine = 11 , lpColumn = 8 , lpStartByte = 109 , lpLength = 6 } , Block [ Expression (Assign - ( Identifier "k" () + ( Identifier + "k" + LP + { lpLine = 12 , lpColumn = 3 , lpStartByte = 121 , lpLength = 1 } , Binary - ( Plus () - , LeftValue (Identifier "i" ()) () - , LeftValue (Identifier "j" ()) () + ( Plus + LP + { lpLine = 12 , lpColumn = 9 , lpStartByte = 127 , lpLength = 1 } + , LeftValue + (Identifier + "i" + LP + { lpLine = 12 , lpColumn = 7 , lpStartByte = 125 , lpLength = 1 }) + LP + { lpLine = 12 , lpColumn = 7 , lpStartByte = 125 , lpLength = 1 } + , LeftValue + (Identifier + "j" + LP + { lpLine = 12 , lpColumn = 11 , lpStartByte = 129 , lpLength = 1 }) + LP + { lpLine = 12 , lpColumn = 11 , lpStartByte = 129 , lpLength = 1 } ) - () + LP + { lpLine = 12 , lpColumn = 7 , lpStartByte = 125 , lpLength = 5 } ) - ()) - () + LP + { lpLine = 12 , lpColumn = 3 , lpStartByte = 121 , lpLength = 9 }) + LP + { lpLine = 12 , lpColumn = 3 , lpStartByte = 121 , lpLength = 10 } , Expression (Assign - ( Identifier "i" () , LeftValue (Identifier "j" ()) () ) ()) - () + ( Identifier + "i" + LP + { lpLine = 13 , lpColumn = 3 , lpStartByte = 134 , lpLength = 1 } + , LeftValue + (Identifier + "j" + LP + { lpLine = 13 , lpColumn = 7 , lpStartByte = 138 , lpLength = 1 }) + LP + { lpLine = 13 , lpColumn = 7 , lpStartByte = 138 , lpLength = 1 } + ) + LP + { lpLine = 13 , lpColumn = 3 , lpStartByte = 134 , lpLength = 5 }) + LP + { lpLine = 13 , lpColumn = 3 , lpStartByte = 134 , lpLength = 6 } , Expression (Assign - ( Identifier "j" () , LeftValue (Identifier "k" ()) () ) ()) - () + ( Identifier + "j" + LP + { lpLine = 14 , lpColumn = 3 , lpStartByte = 143 , lpLength = 1 } + , LeftValue + (Identifier + "k" + LP + { lpLine = 14 , lpColumn = 7 , lpStartByte = 147 , lpLength = 1 }) + LP + { lpLine = 14 , lpColumn = 7 , lpStartByte = 147 , lpLength = 1 } + ) + LP + { lpLine = 14 , lpColumn = 3 , lpStartByte = 143 , lpLength = 5 }) + LP + { lpLine = 14 , lpColumn = 3 , lpStartByte = 143 , lpLength = 6 } , Expression (Assign - ( Identifier "n" () + ( Identifier + "n" + LP + { lpLine = 15 , lpColumn = 3 , lpStartByte = 152 , lpLength = 1 } , Binary - ( Plus () - , LeftValue (Identifier "n" ()) () - , Literal (Int 1 ()) () + ( Plus + LP + { lpLine = 15 , lpColumn = 9 , lpStartByte = 158 , lpLength = 1 } + , LeftValue + (Identifier + "n" + LP + { lpLine = 15 , lpColumn = 7 , lpStartByte = 156 , lpLength = 1 }) + LP + { lpLine = 15 , lpColumn = 7 , lpStartByte = 156 , lpLength = 1 } + , Literal + (Int + 1 + LP + { lpLine = 15 , lpColumn = 11 , lpStartByte = 160 , lpLength = 1 }) + LP + { lpLine = 15 , lpColumn = 11 , lpStartByte = 160 , lpLength = 1 } ) - () + LP + { lpLine = 15 , lpColumn = 7 , lpStartByte = 156 , lpLength = 5 } ) - ()) - () + LP + { lpLine = 15 , lpColumn = 3 , lpStartByte = 152 , lpLength = 9 }) + LP + { lpLine = 15 , lpColumn = 3 , lpStartByte = 152 , lpLength = 10 } , Expression - (Call ( "println" , [ LeftValue (Identifier "k" ()) () ] ) ()) () + (Call + ( "println" + , [ LeftValue + (Identifier + "k" + LP + { lpLine = 16 , lpColumn = 11 , lpStartByte = 173 , lpLength = 1 }) + LP + { lpLine = 16 , lpColumn = 11 , lpStartByte = 173 , lpLength = 1 } + ] + ) + LP + { lpLine = 16 , lpColumn = 3 , lpStartByte = 165 , lpLength = 10 }) + LP + { lpLine = 16 , lpColumn = 3 , lpStartByte = 165 , lpLength = 11 } ] - () + LP + { lpLine = 11 , lpColumn = 16 , lpStartByte = 117 , lpLength = 61 } ) - ()) - () + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 102 , lpLength = 76 }) + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 102 , lpLength = 76 } ] - () + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 178 } From 069b7af1e20d43c1d3a0358d4d50a67ec76b4061 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Wed, 5 Nov 2014 22:50:01 +0100 Subject: [PATCH 41/53] Make Generator polymorphic --- library/Batsh/Generator.hs | 248 +++++++++++++++++++------------------ 1 file changed, 129 insertions(+), 119 deletions(-) diff --git a/library/Batsh/Generator.hs b/library/Batsh/Generator.hs index eb91ddf..778bc31 100644 --- a/library/Batsh/Generator.hs +++ b/library/Batsh/Generator.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE FlexibleInstances #-} module Batsh.Generator where import qualified Data.ByteString @@ -11,98 +12,110 @@ import Data.ByteString.Builder(Builder, stringUtf8, toLazyByteString) -import Batsh.Ast - -renderLiteral :: Literal -> Builder -renderLiteral literal = case literal of - Int num _ -> intDec num - Float num _ -> floatDec num - String str _ -> mconcat [charUtf8 '"', - stringUtf8 str, - charUtf8 '"'] - Bool bool _ -> case bool of - True -> stringUtf8 "true" - False -> stringUtf8 "false" - List list _ -> mconcat [stringUtf8 "[", - renderExpressions list, - stringUtf8 "]"] - -renderLeftValue :: LeftValue -> Builder -renderLeftValue lvalue = case lvalue of - Identifier ident _ -> stringUtf8 ident - ListAccess (lvalue, expr) _ -> mconcat [renderLeftValue lvalue, - stringUtf8 "[", - renderExpression expr, - stringUtf8 "]"] - --- Render a subexpression. Add parenthesis if and only if necessary. -renderSubExpression :: (Operator a) => a -> Expression -> Builder -renderSubExpression operator subExpr = - let rendered = renderExpression subExpr in - let renderedWithParen = mconcat [charUtf8 '(', rendered, charUtf8 ')'] in - case subExpr of - -- if subexpression is a binary expression and the precedence of operator is - -- lower, then add (). E.g. + is less precedent than *. - Binary (subOperator, _, _) _ - | precedence subOperator < precedence operator -> - renderedWithParen - Unary (subOperator, _) _ - | precedence subOperator < precedence operator -> - renderedWithParen - _ -> rendered - -renderUnary :: (UnaryOperator, Expression) -> Builder -renderUnary (operator, expr) = - mconcat [stringUtf8 $ operatorStr operator, - renderSubExpression operator expr] - -renderBinary :: (BinaryOperator, Expression, Expression) -> Builder -renderBinary (operator, left, right) = - mconcat [renderSubExpression operator left, - charUtf8 ' ', - stringUtf8 $ operatorStr operator, - charUtf8 ' ', - renderSubExpression operator right] - -renderExpression :: Expression -> Builder -renderExpression expr = case expr of - LeftValue lvalue _ -> renderLeftValue lvalue - Literal literal _ -> renderLiteral literal - Unary unary _ -> renderUnary unary - Binary binary _ -> renderBinary binary - Assign (lvalue, expr) _ -> mconcat [renderLeftValue lvalue, - stringUtf8 " = ", - renderExpression expr] - Call (ident, exprs) _ -> mconcat [stringUtf8 ident, - charUtf8 '(', - renderExpressions exprs, - charUtf8 ')'] +import Batsh.Ast.Poly + +class Renderable a where + render :: a -> Builder renderSeparateList :: [a] -> String -> (a -> Builder) -> Builder renderSeparateList list separator renderer = case list of [] -> mempty [elem] -> renderer elem (elem : rest) -> mconcat [renderer elem, - stringUtf8 separator, + render separator, renderSeparateList rest separator renderer] -renderExpressions :: [Expression] -> Builder -renderExpressions exprs = renderSeparateList exprs ", " renderExpression - renderIndention :: Int -> Builder -renderIndention level = stringUtf8 (take level $ repeat ' ') - -renderBlock :: [Statement] -> Int -> Builder +renderIndention level = render (take level $ repeat ' ') + +instance Renderable Char where + render char = charUtf8 char + +instance Renderable String where + render str = stringUtf8 str + +instance Renderable (PLiteral a) where + render literal = case literal of + Int num _ -> intDec num + Float num _ -> floatDec num + String str _ -> mconcat [render '"', + render str, + render '"'] + Bool bool _ -> case bool of + True -> render "true" + False -> render "false" + List list _ -> mconcat [render "[", + render list, + render "]"] + +instance Renderable (PLeftValue a) where + render lvalue = case lvalue of + Identifier ident _ -> render ident + ListAccess (lvalue, expr) _ -> mconcat [render lvalue, + render "[", + render expr, + render "]"] + +instance Renderable (PExpression a) where + render expr = case expr of + LeftValue lvalue _ -> render lvalue + Literal literal _ -> render literal + Unary unary _ -> renderUnary unary + Binary binary _ -> renderBinary binary + Assign (lvalue, expr) _ -> mconcat [render lvalue, + render " = ", + render expr] + Call (ident, exprs) _ -> mconcat [render ident, + render '(', + render exprs, + render ')'] + where + -- Render a subexpression. Add parenthesis if and only if necessary. + renderSubExpression :: (Operator a) => a -> (PExpression b) -> Builder + renderSubExpression operator subExpr = + let rendered = render subExpr in + let renderedWithParen = mconcat [render '(', rendered, render ')'] in + case subExpr of + -- if subexpression is a binary expression and the precedence of operator is + -- lower, then add (). E.g. + is less precedent than *. + Binary (subOperator, _, _) _ + | precedence subOperator < precedence operator -> + renderedWithParen + Unary (subOperator, _) _ + | precedence subOperator < precedence operator -> + renderedWithParen + _ -> rendered + + renderUnary :: (PUnaryOperator a, PExpression a) -> Builder + renderUnary (operator, expr) = + mconcat [render $ operatorStr operator, + renderSubExpression operator expr] + + renderBinary :: (PBinaryOperator a, PExpression a, PExpression a) -> Builder + renderBinary (operator, left, right) = + mconcat [renderSubExpression operator left, + render ' ', + render $ operatorStr operator, + render ' ', + renderSubExpression operator right] + +instance Renderable [PExpression a] where + render exprs = renderSeparateList exprs ", " render + +instance Renderable (PStatement a) where + render stmt = renderStatementIndent stmt 0 False + +renderBlock :: [PStatement a] -> Int -> Builder renderBlock stmts level = mconcat - [stringUtf8 "{\n", + [render "{\n", renderSeparateList stmts "\n" $ \stmt -> renderStatementIndent stmt (level + 2) False, - stringUtf8 "\n", + render "\n", renderIndention level, - stringUtf8 "}" + render "}" ] -renderStatementIndent :: Statement -> Int -> Bool -> Builder +renderStatementIndent :: PStatement a -> Int -> Bool -> Builder renderStatementIndent stmt level isClause = if isClause then renderedStmt @@ -111,65 +124,62 @@ renderStatementIndent stmt level isClause = where renderedStmt = case stmt of Comment comment _ -> - mconcat [stringUtf8 "//", - stringUtf8 comment] + mconcat [render "//", + render comment] Block stmts _ -> renderBlock stmts level - Expression expr _ -> withSemicolon $ renderExpression expr + Expression expr _ -> withSemicolon $ render expr If (expr, stmt) _ -> - mconcat [stringUtf8 "if (", - renderExpression expr, - stringUtf8 ") ", + mconcat [render "if (", + render expr, + render ") ", renderClause stmt] IfElse (expr, thenStmt, elseStmt) _ -> - mconcat [stringUtf8 "if (", - renderExpression expr, - stringUtf8 ") ", + mconcat [render "if (", + render expr, + render ") ", renderClause thenStmt, - stringUtf8 " else ", + render " else ", renderClause elseStmt] While (expr, stmt) _ -> - mconcat [stringUtf8 "while (", - renderExpression expr, - stringUtf8 ") ", + mconcat [render "while (", + render expr, + render ") ", renderClause stmt] Global ident _ -> withSemicolon $ - mconcat [stringUtf8 "global ", stringUtf8 ident] + mconcat [render "global ", render ident] Return (Just expr) _ -> withSemicolon $ - mconcat [stringUtf8 "return ", renderExpression expr] - Return Nothing _ -> withSemicolon $ stringUtf8 "return" + mconcat [render "return ", render expr] + Return Nothing _ -> withSemicolon $ render "return" where - withSemicolon builder = mconcat [builder, charUtf8 ';']; + withSemicolon builder = mconcat [builder, render ';']; renderClause stmt = renderStatementIndent stmt level True -renderStatement :: Statement -> Builder -renderStatement stmt = renderStatementIndent stmt 0 False - -renderTopLevel :: TopLevel -> Builder -renderTopLevel toplevel = case toplevel of - Statement stmt _ -> renderStatement stmt - Function (name, params, stmts) _ -> - mconcat [stringUtf8 "function ", - stringUtf8 name, - charUtf8 '(', - renderSeparateList params ", " stringUtf8, - stringUtf8 ") ", - renderBlock stmts 0] - -renderProgram :: Program -> Builder -renderProgram (Program program _) = - mconcat [renderSeparateList program "\n" renderTopLevel, - charUtf8 '\n'] - -generateByteString :: Program -> ByteString -generateByteString program = toLazyByteString $ renderProgram program - -generateString :: Program -> String +instance Renderable (PTopLevel a) where + render toplevel = case toplevel of + Statement stmt _ -> render stmt + Function (name, params, stmts) _ -> + mconcat [render "function ", + render name, + render '(', + renderSeparateList params ", " render, + render ") ", + renderBlock stmts 0] + +instance Renderable (PProgram a) where + render (Program program _) = + mconcat [renderSeparateList program "\n" render, + render '\n'] + +generateByteString :: (PProgram a) -> ByteString +generateByteString program = toLazyByteString $ render program + +generateString :: (PProgram a) -> String generateString program = unpack $ generateByteString program -printToStdout :: Program -> IO () +printToStdout :: (PProgram a) -> IO () printToStdout program = Data.ByteString.Lazy.putStr $ generateByteString program -printToFile :: Program -> FilePath -> IO () +printToFile :: (PProgram a) -> FilePath -> IO () printToFile program filename = Data.ByteString.Lazy.writeFile filename code where code = generateByteString program From 572735d77cd19049599c2df4e9b6974e06896701 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Thu, 6 Nov 2014 20:13:21 +0100 Subject: [PATCH 42/53] Varidic parameter build instead of mconcat --- library/Batsh/Generator.hs | 129 +++++++++++++++++-------------------- test/GeneratorTest.hs | 1 + 2 files changed, 59 insertions(+), 71 deletions(-) diff --git a/library/Batsh/Generator.hs b/library/Batsh/Generator.hs index 778bc31..609e18c 100644 --- a/library/Batsh/Generator.hs +++ b/library/Batsh/Generator.hs @@ -1,6 +1,7 @@ {-# LANGUAGE FlexibleInstances #-} module Batsh.Generator where +import Batsh.Ast.Poly import qualified Data.ByteString import Data.ByteString.Lazy(ByteString, putStr, writeFile) import Data.ByteString.Lazy.Char8(unpack) @@ -12,49 +13,48 @@ import Data.ByteString.Builder(Builder, stringUtf8, toLazyByteString) -import Batsh.Ast.Poly - class Renderable a where - render :: a -> Builder + render :: Renderable a => a -> Builder renderSeparateList :: [a] -> String -> (a -> Builder) -> Builder renderSeparateList list separator renderer = case list of [] -> mempty [elem] -> renderer elem - (elem : rest) -> mconcat [renderer elem, - render separator, - renderSeparateList rest separator renderer] + (elem : rest) -> + build (renderer elem) separator (renderSeparateList rest separator renderer) renderIndention :: Int -> Builder renderIndention level = render (take level $ repeat ' ') +instance Renderable Builder where + render = id + instance Renderable Char where - render char = charUtf8 char + render = charUtf8 instance Renderable String where - render str = stringUtf8 str + render = stringUtf8 + +instance Renderable Int where + render = intDec + +instance Renderable Float where + render = floatDec instance Renderable (PLiteral a) where render literal = case literal of Int num _ -> intDec num Float num _ -> floatDec num - String str _ -> mconcat [render '"', - render str, - render '"'] + String str _ -> build '"' str '"' Bool bool _ -> case bool of True -> render "true" False -> render "false" - List list _ -> mconcat [render "[", - render list, - render "]"] + List list _ -> build "[" list "]" instance Renderable (PLeftValue a) where render lvalue = case lvalue of Identifier ident _ -> render ident - ListAccess (lvalue, expr) _ -> mconcat [render lvalue, - render "[", - render expr, - render "]"] + ListAccess (lvalue, expr) _ -> build lvalue "[" expr "]" instance Renderable (PExpression a) where render expr = case expr of @@ -62,19 +62,13 @@ instance Renderable (PExpression a) where Literal literal _ -> render literal Unary unary _ -> renderUnary unary Binary binary _ -> renderBinary binary - Assign (lvalue, expr) _ -> mconcat [render lvalue, - render " = ", - render expr] - Call (ident, exprs) _ -> mconcat [render ident, - render '(', - render exprs, - render ')'] + Assign (lvalue, expr) _ -> build lvalue " = " expr + Call (ident, exprs) _ -> build ident '(' exprs ')' where -- Render a subexpression. Add parenthesis if and only if necessary. renderSubExpression :: (Operator a) => a -> (PExpression b) -> Builder renderSubExpression operator subExpr = - let rendered = render subExpr in - let renderedWithParen = mconcat [render '(', rendered, render ')'] in + let renderedWithParen = build '(' subExpr ')' in case subExpr of -- if subexpression is a binary expression and the precedence of operator is -- lower, then add (). E.g. + is less precedent than *. @@ -84,20 +78,17 @@ instance Renderable (PExpression a) where Unary (subOperator, _) _ | precedence subOperator < precedence operator -> renderedWithParen - _ -> rendered + _ -> render subExpr renderUnary :: (PUnaryOperator a, PExpression a) -> Builder renderUnary (operator, expr) = - mconcat [render $ operatorStr operator, - renderSubExpression operator expr] + build (operatorStr operator) (renderSubExpression operator expr) renderBinary :: (PBinaryOperator a, PExpression a, PExpression a) -> Builder renderBinary (operator, left, right) = - mconcat [renderSubExpression operator left, - render ' ', - render $ operatorStr operator, - render ' ', - renderSubExpression operator right] + build (renderSubExpression operator left) ' ' + (operatorStr operator) ' ' + (renderSubExpression operator right) instance Renderable [PExpression a] where render exprs = renderSeparateList exprs ", " render @@ -106,69 +97,65 @@ instance Renderable (PStatement a) where render stmt = renderStatementIndent stmt 0 False renderBlock :: [PStatement a] -> Int -> Builder -renderBlock stmts level = mconcat - [render "{\n", - renderSeparateList stmts "\n" $ - \stmt -> renderStatementIndent stmt (level + 2) False, - render "\n", - renderIndention level, - render "}" - ] +renderBlock stmts level = build "{\n" + (renderSeparateList stmts "\n" $ + \stmt -> renderStatementIndent stmt (level + 2) False) + "\n" (renderIndention level) "}" renderStatementIndent :: PStatement a -> Int -> Bool -> Builder renderStatementIndent stmt level isClause = if isClause then renderedStmt else - mconcat [renderIndention level, renderedStmt] + build (renderIndention level) renderedStmt where renderedStmt = case stmt of Comment comment _ -> - mconcat [render "//", - render comment] + build "//" comment Block stmts _ -> renderBlock stmts level Expression expr _ -> withSemicolon $ render expr If (expr, stmt) _ -> - mconcat [render "if (", - render expr, - render ") ", - renderClause stmt] + build "if (" expr ") " (renderClause stmt) IfElse (expr, thenStmt, elseStmt) _ -> - mconcat [render "if (", - render expr, - render ") ", - renderClause thenStmt, - render " else ", - renderClause elseStmt] + build "if (" expr ") " (renderClause thenStmt) + " else " (renderClause elseStmt) While (expr, stmt) _ -> - mconcat [render "while (", - render expr, - render ") ", - renderClause stmt] + build "while (" expr ") " (renderClause stmt) Global ident _ -> withSemicolon $ - mconcat [render "global ", render ident] + build "global " ident Return (Just expr) _ -> withSemicolon $ - mconcat [render "return ", render expr] + build "return " expr Return Nothing _ -> withSemicolon $ render "return" where - withSemicolon builder = mconcat [builder, render ';']; + withSemicolon :: Builder -> Builder + withSemicolon builder = build builder ';' renderClause stmt = renderStatementIndent stmt level True instance Renderable (PTopLevel a) where render toplevel = case toplevel of Statement stmt _ -> render stmt Function (name, params, stmts) _ -> - mconcat [render "function ", - render name, - render '(', - renderSeparateList params ", " render, - render ") ", - renderBlock stmts 0] + build "function " name '(' (renderSeparateList params ", " render) ") " + (renderBlock stmts 0) instance Renderable (PProgram a) where render (Program program _) = - mconcat [renderSeparateList program "\n" render, - render '\n'] + build (renderSeparateList program "\n" render) '\n' + +-- Below is the implementation of varidic parameter of build +class Buildable a where + bPolyConcat :: [Builder] -> a + +instance Buildable Builder where + bPolyConcat accumulator = mconcat $ reverse accumulator + +instance (Buildable a, Renderable b) => Buildable (b -> a) where + bPolyConcat accumulator = \object -> + let rendered = render object in + bPolyConcat (rendered : accumulator) + +build :: Buildable a => a +build = bPolyConcat [] generateByteString :: (PProgram a) -> ByteString generateByteString program = toLazyByteString $ render program diff --git a/test/GeneratorTest.hs b/test/GeneratorTest.hs index 1505ea1..022432b 100644 --- a/test/GeneratorTest.hs +++ b/test/GeneratorTest.hs @@ -11,6 +11,7 @@ testCases = ["arith", "array", "assignment", "block", "command", "comment", testGenerator :: Assertion testGenerator = do + --assertEqual (testpr) 1 2 forM_ testCases $ \testcase -> do let fileName = testCaseDir ++ "/Batsh/" ++ testcase ++ ".batsh" code <- readFile fileName From 68515b7755073351c6cfbc6b931da076995f6437 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Thu, 6 Nov 2014 21:14:14 +0100 Subject: [PATCH 43/53] Split Token from Lexer --- batsh.cabal | 5 +- library/Batsh.hs | 3 +- library/Batsh/Ast.hs | 2 +- library/Batsh/Lexer.x | 54 +----------------- library/Batsh/Parser.y | 123 +++++++++++++++++++++-------------------- library/Batsh/Token.hs | 53 ++++++++++++++++++ test/LexerTest.hs | 1 + test/ParserTest.hs | 2 +- 8 files changed, 124 insertions(+), 119 deletions(-) create mode 100644 library/Batsh/Token.hs diff --git a/batsh.cabal b/batsh.cabal index 934dbd7..64802d9 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -17,8 +17,9 @@ Library Batsh.Ast.Poly, Batsh.Generator, Batsh.Lexer, - Batsh.Parser - Batsh.SymbolTable + Batsh.Parser, + Batsh.SymbolTable, + Batsh.Token Executable batsh Main-Is: Main.hs diff --git a/library/Batsh.hs b/library/Batsh.hs index 4306865..1145ed9 100644 --- a/library/Batsh.hs +++ b/library/Batsh.hs @@ -5,8 +5,9 @@ import qualified Batsh.Generator import qualified Batsh.Lexer import qualified Batsh.Parser import qualified Batsh.SymbolTable as SymbolTable +import qualified Batsh.Token as Token -lex :: String -> [Batsh.Lexer.Lexeme] +lex :: String -> [Token.Lexeme] lex code = Batsh.Lexer.scanLexemes code parse :: String -> Batsh.Ast.Program diff --git a/library/Batsh/Ast.hs b/library/Batsh/Ast.hs index 917e485..4d8b1a6 100644 --- a/library/Batsh/Ast.hs +++ b/library/Batsh/Ast.hs @@ -1,7 +1,7 @@ module Batsh.Ast(module Poly, module Batsh.Ast) where import Batsh.Ast.Poly as Poly -import Batsh.Lexer(LexPos) +import Batsh.Token(LexPos) type AstAnnotation = LexPos diff --git a/library/Batsh/Lexer.x b/library/Batsh/Lexer.x index e919cda..d73abf4 100644 --- a/library/Batsh/Lexer.x +++ b/library/Batsh/Lexer.x @@ -3,6 +3,7 @@ { module Batsh.Lexer where +import Batsh.Token } %wrapper "monad" @@ -85,59 +86,6 @@ tokens :- @identifier { makeStringLexeme Identifier } { - -data Token - = Identifier String - | Comment String - | Int Int - | Float Float - | String String - | TTrue - | TFalse - | If - | Else - | While - | Function - | Global - | Return - | Not - | Semicolon - | Comma - | Plus - | Minus - | Multiply - | Divide - | Modulo - | Concat - | Assign - | Equal - | NotEqual - | ArithEqual - | ArithNotEqual - | Greater - | Less - | GreaterEqual - | LessEqual - | And - | Or - | LParen - | RParen - | LBrack - | RBrack - | LBrace - | RBrace - | LEOF - deriving (Eq, Read, Show) - -data LexPos = LP - { lpLine :: Int, - lpColumn :: Int, - lpStartByte :: Int, - lpLength :: Int } - deriving (Eq, Read, Show) - -data Lexeme = Lex LexPos Token deriving (Eq, Read, Show) - makeLexPos :: AlexPosn -> Int -> LexPos makeLexPos (AlexPn startByte line column) length = LP {lpStartByte = startByte, diff --git a/library/Batsh/Parser.y b/library/Batsh/Parser.y index 81ec5cf..ce00135 100644 --- a/library/Batsh/Parser.y +++ b/library/Batsh/Parser.y @@ -8,6 +8,7 @@ module Batsh.Parser(parse, import qualified Batsh.Ast as Ast import qualified Batsh.Lexer as Lexer +import qualified Batsh.Token as Token import Prelude hiding(span) } @@ -17,49 +18,49 @@ import Prelude hiding(span) %name statement statement %name expression expression -%tokentype { Lexer.Lexeme } +%tokentype { Token.Lexeme } %error { parseError } %token - int { Lexer.Lex _ (Lexer.Int _) } - float { Lexer.Lex _ (Lexer.Float _) } - string { Lexer.Lex _ (Lexer.String _) } - true { Lexer.Lex _ Lexer.TTrue } - false { Lexer.Lex _ Lexer.TFalse } - if { Lexer.Lex _ Lexer.If } - else { Lexer.Lex _ Lexer.Else } - while { Lexer.Lex _ Lexer.While } - function { Lexer.Lex _ Lexer.Function } - global { Lexer.Lex _ Lexer.Global } - return { Lexer.Lex _ Lexer.Return } - '!' { Lexer.Lex _ Lexer.Not } - ';' { Lexer.Lex _ Lexer.Semicolon } - ',' { Lexer.Lex _ Lexer.Comma } - '+' { Lexer.Lex _ Lexer.Plus } - '-' { Lexer.Lex _ Lexer.Minus } - '*' { Lexer.Lex _ Lexer.Multiply } - '/' { Lexer.Lex _ Lexer.Divide } - '%' { Lexer.Lex _ Lexer.Modulo } - '++' { Lexer.Lex _ Lexer.Concat } - '=' { Lexer.Lex _ Lexer.Assign } - '==' { Lexer.Lex _ Lexer.Equal } - '!=' { Lexer.Lex _ Lexer.NotEqual } - '===' { Lexer.Lex _ Lexer.ArithEqual } - '!==' { Lexer.Lex _ Lexer.ArithNotEqual } - '>' { Lexer.Lex _ Lexer.Greater } - '<' { Lexer.Lex _ Lexer.Less } - '>=' { Lexer.Lex _ Lexer.GreaterEqual } - '<=' { Lexer.Lex _ Lexer.LessEqual } - '&&' { Lexer.Lex _ Lexer.And } - '||' { Lexer.Lex _ Lexer.Or } - '(' { Lexer.Lex _ Lexer.LParen } - ')' { Lexer.Lex _ Lexer.RParen } - '[' { Lexer.Lex _ Lexer.LBrack } - ']' { Lexer.Lex _ Lexer.RBrack } - '{' { Lexer.Lex _ Lexer.LBrace } - '}' { Lexer.Lex _ Lexer.RBrace } - comment { Lexer.Lex _ (Lexer.Comment _) } - ident { Lexer.Lex _ (Lexer.Identifier _) } + int { Token.Lex _ (Token.Int _) } + float { Token.Lex _ (Token.Float _) } + string { Token.Lex _ (Token.String _) } + true { Token.Lex _ Token.TTrue } + false { Token.Lex _ Token.TFalse } + if { Token.Lex _ Token.If } + else { Token.Lex _ Token.Else } + while { Token.Lex _ Token.While } + function { Token.Lex _ Token.Function } + global { Token.Lex _ Token.Global } + return { Token.Lex _ Token.Return } + '!' { Token.Lex _ Token.Not } + ';' { Token.Lex _ Token.Semicolon } + ',' { Token.Lex _ Token.Comma } + '+' { Token.Lex _ Token.Plus } + '-' { Token.Lex _ Token.Minus } + '*' { Token.Lex _ Token.Multiply } + '/' { Token.Lex _ Token.Divide } + '%' { Token.Lex _ Token.Modulo } + '++' { Token.Lex _ Token.Concat } + '=' { Token.Lex _ Token.Assign } + '==' { Token.Lex _ Token.Equal } + '!=' { Token.Lex _ Token.NotEqual } + '===' { Token.Lex _ Token.ArithEqual } + '!==' { Token.Lex _ Token.ArithNotEqual } + '>' { Token.Lex _ Token.Greater } + '<' { Token.Lex _ Token.Less } + '>=' { Token.Lex _ Token.GreaterEqual } + '<=' { Token.Lex _ Token.LessEqual } + '&&' { Token.Lex _ Token.And } + '||' { Token.Lex _ Token.Or } + '(' { Token.Lex _ Token.LParen } + ')' { Token.Lex _ Token.RParen } + '[' { Token.Lex _ Token.LBrack } + ']' { Token.Lex _ Token.RBrack } + '{' { Token.Lex _ Token.LBrace } + '}' { Token.Lex _ Token.RBrace } + comment { Token.Lex _ (Token.Comment _) } + ident { Token.Lex _ (Token.Identifier _) } %right if else %right '=' @@ -185,39 +186,39 @@ idents : { [] } { -- Get the position information of a Lexeme -pos :: Lexer.Lexeme -> Lexer.LexPos -pos (Lexer.Lex pos _) = pos +pos :: Token.Lexeme -> Token.LexPos +pos (Token.Lex pos _) = pos -- Get the position information of a AstNode -apos :: Ast.AstNode a => a Lexer.LexPos -> Lexer.LexPos +apos :: Ast.AstNode a => a Token.LexPos -> Token.LexPos apos node = Ast.annot node -- Merge two positions from leftmost to rightmost -span :: Lexer.LexPos -> Lexer.LexPos -> Lexer.LexPos +span :: Token.LexPos -> Token.LexPos -> Token.LexPos span left right = - Lexer.LP - { Lexer.lpStartByte = start, - Lexer.lpLength = length, - Lexer.lpLine = Lexer.lpLine left, - Lexer.lpColumn = Lexer.lpColumn left} + Token.LP + { Token.lpStartByte = start, + Token.lpLength = length, + Token.lpLine = Token.lpLine left, + Token.lpColumn = Token.lpColumn left} where length = end - start - start = Lexer.lpStartByte left - end = Lexer.lpStartByte right + Lexer.lpLength right + start = Token.lpStartByte left + end = Token.lpStartByte right + Token.lpLength right -- Extract internal data of the Lexeme -exInt :: Lexer.Lexeme -> Int -exInt (Lexer.Lex _ (Lexer.Int num)) = num +exInt :: Token.Lexeme -> Int +exInt (Token.Lex _ (Token.Int num)) = num -exFlt :: Lexer.Lexeme -> Float -exFlt (Lexer.Lex _ (Lexer.Float num)) = num +exFlt :: Token.Lexeme -> Float +exFlt (Token.Lex _ (Token.Float num)) = num -exStr :: Lexer.Lexeme -> String -exStr (Lexer.Lex _ (Lexer.Identifier str)) = str -exStr (Lexer.Lex _ (Lexer.Comment str)) = str -exStr (Lexer.Lex _ (Lexer.String str)) = str +exStr :: Token.Lexeme -> String +exStr (Token.Lex _ (Token.Identifier str)) = str +exStr (Token.Lex _ (Token.Comment str)) = str +exStr (Token.Lex _ (Token.String str)) = str -parseError :: [Lexer.Lexeme] -> a +parseError :: [Token.Lexeme] -> a parseError _ = error "Parse error" parse :: String -> Ast.Program @@ -234,5 +235,5 @@ parseExpression = expression . Lexer.scanLexemes -- TODO add pos information to AST scanTokens code = map stripPos (Lexer.scanLexemes code) - where stripPos (Lexer.Lex _ token) = token + where stripPos (Token.Lex _ token) = token } diff --git a/library/Batsh/Token.hs b/library/Batsh/Token.hs new file mode 100644 index 0000000..286a2ba --- /dev/null +++ b/library/Batsh/Token.hs @@ -0,0 +1,53 @@ +module Batsh.Token where + +data Token + = Identifier String + | Comment String + | Int Int + | Float Float + | String String + | TTrue + | TFalse + | If + | Else + | While + | Function + | Global + | Return + | Not + | Semicolon + | Comma + | Plus + | Minus + | Multiply + | Divide + | Modulo + | Concat + | Assign + | Equal + | NotEqual + | ArithEqual + | ArithNotEqual + | Greater + | Less + | GreaterEqual + | LessEqual + | And + | Or + | LParen + | RParen + | LBrack + | RBrack + | LBrace + | RBrace + | LEOF + deriving (Eq, Read, Show) + +data LexPos = LP + { lpLine :: Int, + lpColumn :: Int, + lpStartByte :: Int, + lpLength :: Int } + deriving (Eq, Read, Show) + +data Lexeme = Lex LexPos Token deriving (Eq, Read, Show) diff --git a/test/LexerTest.hs b/test/LexerTest.hs index 56e0b21..ed6196c 100644 --- a/test/LexerTest.hs +++ b/test/LexerTest.hs @@ -1,6 +1,7 @@ module LexerTest where import Batsh.Lexer +import Batsh.Token import Test.HUnit testLexer :: Assertion diff --git a/test/ParserTest.hs b/test/ParserTest.hs index 0abe7d6..5616554 100644 --- a/test/ParserTest.hs +++ b/test/ParserTest.hs @@ -2,7 +2,7 @@ module ParserTest where import qualified Batsh import Batsh.Ast -import Batsh.Lexer(lpLine, lpColumn, lpStartByte, lpLength, LexPos(LP)) +import Batsh.Token(lpLine, lpColumn, lpStartByte, lpLength, LexPos(LP)) import Batsh.Parser import Control.Monad import Test.HUnit From 4e7ce08f8aee581933e968013f865fdf38e32229 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Thu, 6 Nov 2014 21:17:44 +0100 Subject: [PATCH 44/53] Hide catch from Prelude in SymbolTableTest --- test/SymbolTableTest.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/SymbolTableTest.hs b/test/SymbolTableTest.hs index 736a9e8..2173114 100644 --- a/test/SymbolTableTest.hs +++ b/test/SymbolTableTest.hs @@ -6,6 +6,7 @@ import Batsh.SymbolTable import Control.Exception import Control.Monad import qualified Data.Map.Strict as SMap +import Prelude hiding(catch) import Test.HUnit testSymbolTable :: Assertion From d445cfa11d9649c244d6c906fa70e6a83c236596 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Thu, 6 Nov 2014 21:36:25 +0100 Subject: [PATCH 45/53] Specify build-tools alex >= 3.1.3, happy >= 1.19.4 --- .travis.yml | 4 ++++ batsh.cabal | 1 + 2 files changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 2fb1093..abba6be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,3 +2,7 @@ language: haskell ghc: - 7.6 - 7.4 +install: + - cabal install --only-dependencies --enable-tests + - cabal install alex-3.1.3 + - cabal install happy-1.19.4 diff --git a/batsh.cabal b/batsh.cabal index 64802d9..df85017 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -12,6 +12,7 @@ Build-Type: Simple Library Hs-Source-Dirs: library Build-Depends: array, base, bytestring == 0.10.4.0, containers >= 0.5 + Build-Tools: alex >= 3.1.3, happy >= 1.19.4 Exposed-Modules: Batsh, Batsh.Ast, Batsh.Ast.Poly, From 3b15635049e31fbe961e2087623412576f1f1ec6 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Fri, 7 Nov 2014 19:50:01 +0100 Subject: [PATCH 46/53] Skeleton of TypeCheck --- batsh.cabal | 4 +++- library/Batsh/Ast/Typed.hs | 30 ++++++++++++++++++++++++++++++ library/Batsh/TypeCheck.hs | 12 ++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 library/Batsh/Ast/Typed.hs create mode 100644 library/Batsh/TypeCheck.hs diff --git a/batsh.cabal b/batsh.cabal index df85017..7919182 100644 --- a/batsh.cabal +++ b/batsh.cabal @@ -16,11 +16,13 @@ Library Exposed-Modules: Batsh, Batsh.Ast, Batsh.Ast.Poly, + Batsh.Ast.Typed, Batsh.Generator, Batsh.Lexer, Batsh.Parser, Batsh.SymbolTable, - Batsh.Token + Batsh.Token, + Batsh.TypeCheck Executable batsh Main-Is: Main.hs diff --git a/library/Batsh/Ast/Typed.hs b/library/Batsh/Ast/Typed.hs new file mode 100644 index 0000000..896701a --- /dev/null +++ b/library/Batsh/Ast/Typed.hs @@ -0,0 +1,30 @@ +module Batsh.Ast.Typed(module Poly, module Batsh.Ast.Typed) where + +import Batsh.Ast.Poly as Poly +import Batsh.Token(LexPos) + +data Type = TInt | TFloat | TString | TList + +data TypeAnno = TypeAnno Type LexPos + +type Literal = PLiteral TypeAnno + +type LeftValue = PLeftValue TypeAnno + +type UnaryOperator = PUnaryOperator TypeAnno + +type BinaryOperator = PBinaryOperator TypeAnno + +type Expression = PExpression TypeAnno + +type Statement = PStatement TypeAnno + +type TopLevel = PTopLevel TypeAnno + +type Program = PProgram TypeAnno + +nodeType :: AstNode a => a TypeAnno -> Type +nodeType node = typ where TypeAnno typ _ = annot node + +nodePos :: AstNode a => a TypeAnno -> LexPos +nodePos node = pos where TypeAnno _ pos = annot node diff --git a/library/Batsh/TypeCheck.hs b/library/Batsh/TypeCheck.hs new file mode 100644 index 0000000..951204f --- /dev/null +++ b/library/Batsh/TypeCheck.hs @@ -0,0 +1,12 @@ +{-# LANGUAGE FlexibleInstances #-} +module Batsh.TypeCheck where + +import qualified Batsh.Ast as Raw +import Batsh.Ast.Typed + +class TypeCheckable a where + typeCheck :: a -> b + +--instance TypeCheckable Raw.Literal where +-- typeCheck literal = case literal of +-- Int num pos -> Int num () From 050bb5d6c93d101358a52fd3002c1e1490e91242 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Fri, 7 Nov 2014 20:22:31 +0100 Subject: [PATCH 47/53] Use record to rewrite Ast --- library/Batsh/Ast/Poly.hs | 227 ++-- library/Batsh/Ast/Typed.hs | 2 +- library/Batsh/Generator.hs | 35 +- library/Batsh/Parser.y | 22 +- library/Batsh/SymbolTable.hs | 20 +- library/Batsh/TypeCheck.hs | 30 +- test/ParserTest.hs | 18 +- test/testcase/Batsh/arith.ast | 1777 ++++++++++++++++++++-------- test/testcase/Batsh/array.ast | 1749 +++++++++++++++++++-------- test/testcase/Batsh/assignment.ast | 731 ++++++++---- test/testcase/Batsh/block.ast | 322 +++-- test/testcase/Batsh/command.ast | 388 ++++-- test/testcase/Batsh/comment.ast | 256 ++-- test/testcase/Batsh/exists.ast | 488 +++++--- test/testcase/Batsh/function.ast | 1510 +++++++++++++++-------- test/testcase/Batsh/if.ast | 1521 ++++++++++++++++-------- test/testcase/Batsh/recursion.ast | 1738 ++++++++++++++++++--------- test/testcase/Batsh/string.ast | 1351 +++++++++++++++------ test/testcase/Batsh/while.ast | 1090 ++++++++++++----- 19 files changed, 9276 insertions(+), 3999 deletions(-) diff --git a/library/Batsh/Ast/Poly.hs b/library/Batsh/Ast/Poly.hs index 998def0..2ef146e 100644 --- a/library/Batsh/Ast/Poly.hs +++ b/library/Batsh/Ast/Poly.hs @@ -1,68 +1,139 @@ module Batsh.Ast.Poly where -data PLiteral a - = Bool Bool a - | Int Int a - | Float Float a - | String String a - | List [PExpression a] a +data PLiteral annot_type + = Bool {literal_bool :: Bool, literal_annot :: annot_type} + | Int {literal_int :: Int, literal_annot :: annot_type} + | Float {literal_float :: Float, literal_annot :: annot_type} + | String {literal_str :: String, literal_annot :: annot_type} + | List {literal_list :: [PExpression annot_type], literal_annot :: annot_type} deriving (Eq, Read, Show) -data PLeftValue a - = Identifier Identifier a - | ListAccess (PLeftValue a, PExpression a) a +data PLeftValue annot_type + = Identifier { + lvalue_ident :: Identifier, + lvalue_annot :: annot_type + } + | ListAccess { + lvalue_var :: PLeftValue annot_type, + lvalue_index :: PExpression annot_type, + lvalue_annot :: annot_type + } deriving (Eq, Read, Show) -data PUnaryOperator a - = Not a - | Negate a +data PUnaryOperator annot_type + = Not {unOp_annot :: annot_type} + | Negate {unOp_annot :: annot_type} deriving (Eq, Read, Show) -data PBinaryOperator a - = Plus a - | Minus a - | Multiply a - | Divide a - | Modulo a - | Concat a - | Equal a - | NotEqual a - | ArithEqual a - | ArithNotEqual a - | Greater a - | Less a - | GreaterEqual a - | LessEqual a - | And a - | Or a +data PBinaryOperator annot_type + = Plus {binOp_annot :: annot_type} + | Minus {binOp_annot :: annot_type} + | Multiply {binOp_annot :: annot_type} + | Divide {binOp_annot :: annot_type} + | Modulo {binOp_annot :: annot_type} + | Concat {binOp_annot :: annot_type} + | Equal {binOp_annot :: annot_type} + | NotEqual {binOp_annot :: annot_type} + | ArithEqual {binOp_annot :: annot_type} + | ArithNotEqual {binOp_annot :: annot_type} + | Greater {binOp_annot :: annot_type} + | Less {binOp_annot :: annot_type} + | GreaterEqual {binOp_annot :: annot_type} + | LessEqual {binOp_annot :: annot_type} + | And {binOp_annot :: annot_type} + | Or {binOp_annot :: annot_type} deriving (Eq, Read, Show) -data PExpression a - = LeftValue (PLeftValue a) a - | Literal (PLiteral a) a - | Unary (PUnaryOperator a, PExpression a) a - | Binary (PBinaryOperator a, PExpression a, PExpression a) a - | Assign (PLeftValue a, PExpression a) a - | Call (FunctionName, [PExpression a]) a +data PExpression annot_type + = LeftValue { + expr_lvalue :: PLeftValue annot_type, + expr_annot :: annot_type + } + | Literal { + expr_literal :: PLiteral annot_type, + expr_annot :: annot_type + } + | Unary { + expr_unOp :: PUnaryOperator annot_type, + expr_subExpr :: PExpression annot_type, + expr_annot :: annot_type + } + | Binary { + expr_binOp :: PBinaryOperator annot_type, + expr_left :: PExpression annot_type, + expr_right :: PExpression annot_type, + expr_annot :: annot_type + } + | Assign { + expr_lvalue :: PLeftValue annot_type, + expr_subExpr :: PExpression annot_type, + expr_annot :: annot_type + } + | Call { + expr_func :: FunctionName, + expr_params :: [PExpression annot_type], + expr_annot :: annot_type + } deriving (Eq, Read, Show) -data PStatement a - = Comment String a - | Block [PStatement a] a - | Expression (PExpression a) a - | If (PExpression a, PStatement a) a - | IfElse (PExpression a, PStatement a, PStatement a) a - | While (PExpression a, PStatement a) a - | Global Identifier a - | Return (Maybe (PExpression a)) a +data PStatement annot_type + = Comment { + stmt_comment :: String, + stmt_annot :: annot_type + } + | Block { + stmt_stmts :: [PStatement annot_type], + stmt_annot :: annot_type + } + | Expression { + stmt_expr :: PExpression annot_type, + stmt_annot :: annot_type + } + | If { + stmt_expr :: PExpression annot_type, + stmt_then :: PStatement annot_type, + stmt_annot :: annot_type + } + | IfElse { + stmt_expr :: PExpression annot_type, + stmt_then :: PStatement annot_type, + stmt_else :: PStatement annot_type, + stmt_annot :: annot_type + } + | While { + stmt_expr :: PExpression annot_type, + stmt_loop :: PStatement annot_type, + stmt_annot :: annot_type + } + | Global { + stmt_ident :: Identifier, + stmt_annot :: annot_type + } + | Return { + stmt_retval :: Maybe (PExpression annot_type), + stmt_annot :: annot_type + } deriving (Eq, Read, Show) -data PTopLevel a - = Statement (PStatement a) a - | Function (FunctionName, [Parameter], [PStatement a]) a +data PTopLevel annot_type + = Statement { + toplevel_stmt :: PStatement annot_type, + toplevel_annot :: annot_type + } + | Function { + toplevel_func :: FunctionName, + toplevel_params :: [Parameter], + toplevel_stmts :: [PStatement annot_type], + toplevel_annot :: annot_type + } deriving (Eq, Read, Show) -data PProgram a = Program [PTopLevel a] a deriving (Eq, Read, Show) +data PProgram annot_type + = Program { + program_topls :: [PTopLevel annot_type], + program_annot :: annot_type + } + deriving (Eq, Read, Show) type Identifier = String @@ -74,70 +145,28 @@ class AstNode a where annot :: a annot -> annot instance AstNode PLiteral where - annot node = case node of - Bool _ annot -> annot - Int _ annot -> annot - Float _ annot -> annot - String _ annot -> annot - List _ annot -> annot + annot = literal_annot instance AstNode PLeftValue where - annot node = case node of - Identifier _ annot -> annot - ListAccess _ annot -> annot + annot = lvalue_annot instance AstNode PUnaryOperator where - annot node = case node of - Not annot -> annot - Negate annot -> annot + annot = unOp_annot instance AstNode PBinaryOperator where - annot node = case node of - Plus annot -> annot - Minus annot -> annot - Multiply annot -> annot - Divide annot -> annot - Modulo annot -> annot - Concat annot -> annot - Equal annot -> annot - NotEqual annot -> annot - ArithEqual annot -> annot - ArithNotEqual annot -> annot - Greater annot -> annot - Less annot -> annot - GreaterEqual annot -> annot - LessEqual annot -> annot - And annot -> annot - Or annot -> annot + annot = binOp_annot instance AstNode PExpression where - annot node = case node of - LeftValue _ annot -> annot - Literal _ annot -> annot - Unary _ annot -> annot - Binary _ annot -> annot - Assign _ annot -> annot - Call _ annot -> annot + annot = expr_annot instance AstNode PStatement where - annot node = case node of - Comment _ annot -> annot - Block _ annot -> annot - Expression _ annot -> annot - If _ annot -> annot - IfElse _ annot -> annot - While _ annot -> annot - Global _ annot -> annot - Return _ annot -> annot + annot = stmt_annot instance AstNode PTopLevel where - annot node = case node of - Statement _ annot -> annot - Function _ annot -> annot + annot = toplevel_annot instance AstNode PProgram where - annot node = case node of - Program _ annot -> annot + annot = program_annot class Operator a where precedence :: a -> Int diff --git a/library/Batsh/Ast/Typed.hs b/library/Batsh/Ast/Typed.hs index 896701a..a1cd6c6 100644 --- a/library/Batsh/Ast/Typed.hs +++ b/library/Batsh/Ast/Typed.hs @@ -3,7 +3,7 @@ module Batsh.Ast.Typed(module Poly, module Batsh.Ast.Typed) where import Batsh.Ast.Poly as Poly import Batsh.Token(LexPos) -data Type = TInt | TFloat | TString | TList +data Type = TBool | TInt | TFloat | TString | TList | TNoType data TypeAnno = TypeAnno Type LexPos diff --git a/library/Batsh/Generator.hs b/library/Batsh/Generator.hs index 609e18c..13a0911 100644 --- a/library/Batsh/Generator.hs +++ b/library/Batsh/Generator.hs @@ -54,16 +54,20 @@ instance Renderable (PLiteral a) where instance Renderable (PLeftValue a) where render lvalue = case lvalue of Identifier ident _ -> render ident - ListAccess (lvalue, expr) _ -> build lvalue "[" expr "]" + ListAccess lvalue expr _ -> build lvalue "[" expr "]" instance Renderable (PExpression a) where render expr = case expr of LeftValue lvalue _ -> render lvalue Literal literal _ -> render literal - Unary unary _ -> renderUnary unary - Binary binary _ -> renderBinary binary - Assign (lvalue, expr) _ -> build lvalue " = " expr - Call (ident, exprs) _ -> build ident '(' exprs ')' + Unary operator expr _ -> + build (operatorStr operator) (renderSubExpression operator expr) + Binary operator left right _ -> + build (renderSubExpression operator left) ' ' + (operatorStr operator) ' ' + (renderSubExpression operator right) + Assign lvalue expr _ -> build lvalue " = " expr + Call ident exprs _ -> build ident '(' exprs ')' where -- Render a subexpression. Add parenthesis if and only if necessary. renderSubExpression :: (Operator a) => a -> (PExpression b) -> Builder @@ -72,23 +76,14 @@ instance Renderable (PExpression a) where case subExpr of -- if subexpression is a binary expression and the precedence of operator is -- lower, then add (). E.g. + is less precedent than *. - Binary (subOperator, _, _) _ + Binary subOperator _ _ _ | precedence subOperator < precedence operator -> renderedWithParen - Unary (subOperator, _) _ + Unary subOperator _ _ | precedence subOperator < precedence operator -> renderedWithParen _ -> render subExpr - renderUnary :: (PUnaryOperator a, PExpression a) -> Builder - renderUnary (operator, expr) = - build (operatorStr operator) (renderSubExpression operator expr) - - renderBinary :: (PBinaryOperator a, PExpression a, PExpression a) -> Builder - renderBinary (operator, left, right) = - build (renderSubExpression operator left) ' ' - (operatorStr operator) ' ' - (renderSubExpression operator right) instance Renderable [PExpression a] where render exprs = renderSeparateList exprs ", " render @@ -114,12 +109,12 @@ renderStatementIndent stmt level isClause = build "//" comment Block stmts _ -> renderBlock stmts level Expression expr _ -> withSemicolon $ render expr - If (expr, stmt) _ -> + If expr stmt _ -> build "if (" expr ") " (renderClause stmt) - IfElse (expr, thenStmt, elseStmt) _ -> + IfElse expr thenStmt elseStmt _ -> build "if (" expr ") " (renderClause thenStmt) " else " (renderClause elseStmt) - While (expr, stmt) _ -> + While expr stmt _ -> build "while (" expr ") " (renderClause stmt) Global ident _ -> withSemicolon $ build "global " ident @@ -134,7 +129,7 @@ renderStatementIndent stmt level isClause = instance Renderable (PTopLevel a) where render toplevel = case toplevel of Statement stmt _ -> render stmt - Function (name, params, stmts) _ -> + Function name params stmts _ -> build "function " name '(' (renderSeparateList params ", " render) ") " (renderBlock stmts 0) diff --git a/library/Batsh/Parser.y b/library/Batsh/Parser.y index ce00135..f7bb2b8 100644 --- a/library/Batsh/Parser.y +++ b/library/Batsh/Parser.y @@ -80,7 +80,7 @@ program : toplevels { Ast.Program $1 $ toplevel : statement { Ast.Statement $1 (apos $1) } | function ident '(' idents ')' - '{' statements '}' { Ast.Function (exStr $2, $4, $7) + '{' statements '}' { Ast.Function (exStr $2) $4 $7 $ span (pos $1) (pos $8)} statement : comment { Ast.Comment (exStr $1) @@ -99,26 +99,26 @@ statement : comment { Ast.Comment (exStr $1) | loop_statement { $1 } if_statement : if '(' expression ')' - statement %prec if { Ast.If ($3, $5) + statement %prec if { Ast.If $3 $5 $ span (pos $1) (apos $5) } | if '(' expression ')' - statement else statement { Ast.IfElse ($3, $5, $7) + statement else statement { Ast.IfElse $3 $5 $7 $ span (pos $1) (apos $7) } loop_statement: while '(' expression ')' - statement { Ast.While ($3, $5) + statement { Ast.While $3 $5 $ span (pos $1) (apos $5) } expression : leftvalue { Ast.LeftValue $1 (apos $1) } | literal { Ast.Literal $1 (apos $1) } - | ident '(' expressions ')' { Ast.Call (exStr $1, $3) + | ident '(' expressions ')' { Ast.Call (exStr $1) $3 $ span (pos $1) (pos $4) } | '(' expression ')' { $2 } - | unary { let (unary, pos) = $1 in - Ast.Unary unary pos } - | binary { let (binary, pos) = $1 in - Ast.Binary binary pos } - | leftvalue '=' expression { Ast.Assign ($1, $3) + | unary { let ((op, sub), pos) = $1 in + Ast.Unary op sub pos } + | binary { let ((op, left, right), pos) = $1 in + Ast.Binary op left right pos } + | leftvalue '=' expression { Ast.Assign $1 $3 $ span (apos $1) (apos $3) } unary : '!' expression { (Ast.Not (pos $1), $2), @@ -167,7 +167,7 @@ literal : true { Ast.Bool True (pos $1) } | '[' expressions ']' { Ast.List $2 (pos $1) } leftvalue : ident { Ast.Identifier (exStr $1) (pos $1) } - | leftvalue '[' expression ']' { Ast.ListAccess ($1, $3) + | leftvalue '[' expression ']' { Ast.ListAccess $1 $3 $ span (apos $1) (pos $4) } toplevels : { [] } diff --git a/library/Batsh/SymbolTable.hs b/library/Batsh/SymbolTable.hs index a03a16a..f7bf1eb 100644 --- a/library/Batsh/SymbolTable.hs +++ b/library/Batsh/SymbolTable.hs @@ -49,7 +49,7 @@ create (Program program _) = SymbolTable $ SMap.fromList $ (SGlobal, globalTable) : functionTables where (functions, topLevelStmts) = List.partition (\topl -> case topl of - Function _ _ -> True + Function _ _ _ _ -> True Statement _ _ -> False ) program; stmts = map (\(Statement stmt _) -> stmt) topLevelStmts @@ -61,7 +61,7 @@ create (Program program _) = functionTables :: [(Scope, Table)] functionTables = map processFunction functions addFuncDef :: MapIdentifierSymbol -> TopLevel -> MapIdentifierSymbol - addFuncDef table (Function (func, _, _) _) = + addFuncDef table (Function func _ _ _) = let scope = SGlobal in -- functions can be defined only in the global scope let symbol = (func, STFunction, scope) in if not (SMap.member func table) then @@ -70,7 +70,7 @@ create (Program program _) = symbolTableError $ "Redefinition of function '" ++ func ++ "'" processFunction :: TopLevel -> (Scope, Table) -processFunction (Function (func, params, stmts) _) = +processFunction (Function func params stmts _) = (scope, table) where scope = SFunction func; @@ -92,14 +92,14 @@ processStatement :: Table -> Scope -> Statement -> Table processStatement table scope stmt = case stmt of Block stmts _ -> processStatements table scope stmts -- TODO block scope Expression expr _ -> processExpression table scope expr - If (expr, subStmt) _ -> + If expr subStmt _ -> let exprTable = processExpression table scope expr in processStatement exprTable scope subStmt - IfElse (expr, thenStmt, elseStmt) _ -> + IfElse expr thenStmt elseStmt _ -> let exprTable = processExpression table scope expr in let thenTable = processStatement exprTable scope thenStmt in processStatement thenTable scope elseStmt - While (expr, subStmt) _ -> + While expr subStmt _ -> let exprTable = processExpression table scope expr in processStatement exprTable scope subStmt Global ident _ -> processIdentifier table SGlobal ident @@ -112,9 +112,9 @@ processStatements table scope stmts = processExpression :: Table -> Scope -> Expression -> Table processExpression table scope expr = case expr of - Assign (lvalue, subExpr) _ -> processLeftValue table scope lvalue - Unary (_, subExpr) _ -> processExpression table scope subExpr - Binary (_, left, right) _ -> + Assign lvalue subExpr _ -> processLeftValue table scope lvalue + Unary _ subExpr _ -> processExpression table scope subExpr + Binary _ left right _ -> let exprTable = processExpression table scope left in processExpression exprTable scope right _ -> table @@ -122,7 +122,7 @@ processExpression table scope expr = case expr of processLeftValue :: Table -> Scope -> LeftValue -> Table processLeftValue table scope lvalue = case lvalue of Identifier ident _ -> processIdentifier table scope ident - ListAccess (lvalue, subExpr) _ -> + ListAccess lvalue subExpr _ -> let lvalueTable = processLeftValue table scope lvalue in processExpression lvalueTable scope subExpr diff --git a/library/Batsh/TypeCheck.hs b/library/Batsh/TypeCheck.hs index 951204f..a292bdb 100644 --- a/library/Batsh/TypeCheck.hs +++ b/library/Batsh/TypeCheck.hs @@ -1,12 +1,30 @@ -{-# LANGUAGE FlexibleInstances #-} module Batsh.TypeCheck where import qualified Batsh.Ast as Raw import Batsh.Ast.Typed -class TypeCheckable a where - typeCheck :: a -> b +class AstNode a => TypeCheckable a where + typeCheck :: a Raw.AstAnnotation -> a TypeAnno ---instance TypeCheckable Raw.Literal where --- typeCheck literal = case literal of --- Int num pos -> Int num () +typeCheckList :: TypeCheckable a => [a Raw.AstAnnotation] -> [a TypeAnno] +typeCheckList list = map typeCheck list + +instance TypeCheckable PLiteral where + typeCheck literal = case literal of + Bool bool pos -> Bool bool (TypeAnno TBool pos) + Int num pos -> Int num (TypeAnno TInt pos) + Float num pos -> Float num (TypeAnno TFloat pos) + String str pos -> String str (TypeAnno TString pos) + List exprs pos -> List (typeCheckList exprs) (TypeAnno TList pos) + +-- All variables are considered as String +instance TypeCheckable PLeftValue where + typeCheck literal = case literal of + Identifier ident pos -> Identifier ident (TypeAnno TString pos) + ListAccess lvalue expr pos -> + ListAccess (typeCheck lvalue) (typeCheck expr) (TypeAnno TString pos) + +instance TypeCheckable PExpression where + typeCheck expr = case expr of + LeftValue lvalue pos -> LeftValue (typeCheck lvalue) (TypeAnno TString pos) + Literal literal pos -> Literal (typeCheck literal) (TypeAnno TString pos) diff --git a/test/ParserTest.hs b/test/ParserTest.hs index 5616554..4b367ea 100644 --- a/test/ParserTest.hs +++ b/test/ParserTest.hs @@ -18,15 +18,17 @@ testParser = do let testStatement = testAst parseStatement let testExpression = testAst parseExpression -- Expression - testExpression "3" $ Literal (Int 3 (LP {lpLine = 1, lpColumn = 1, - lpStartByte = 0, lpLength = 1})) (LP {lpLine = 1, lpColumn = 1, - lpStartByte = 0, lpLength = 1}) + testExpression "3" Literal {expr_literal = Int {literal_int = 3, + literal_annot = LP {lpLine = 1, lpColumn = 1, lpStartByte = 0, + lpLength = 1}}, expr_annot = LP {lpLine = 1, lpColumn = 1, lpStartByte = 0, + lpLength = 1}} -- Statement - testStatement "func(4);" $ Expression (Call ("func",[Literal (Int 4 ( - LP {lpLine = 1, lpColumn = 6, lpStartByte = 5, lpLength = 1})) (LP { - lpLine = 1, lpColumn = 6, lpStartByte = 5, lpLength = 1})]) (LP { - lpLine = 1, lpColumn = 1, lpStartByte = 0, lpLength = 7})) (LP { - lpLine = 1, lpColumn = 1, lpStartByte = 0, lpLength = 8}) + testStatement "func(4);" Expression {stmt_expr = Call {expr_func = "func", + expr_params = [Literal {expr_literal = Int {literal_int = 4, literal_annot = + LP {lpLine = 1, lpColumn = 6, lpStartByte = 5, lpLength = 1}}, expr_annot = + LP {lpLine = 1, lpColumn = 6, lpStartByte = 5, lpLength = 1}}], expr_annot = + LP {lpLine = 1, lpColumn = 1, lpStartByte = 0, lpLength = 7}}, stmt_annot = + LP {lpLine = 1, lpColumn = 1, lpStartByte = 0, lpLength = 8}} testCaseDir = "test/testcase" testCases = ["arith", "array", "assignment", "block", "command", "comment", diff --git a/test/testcase/Batsh/arith.ast b/test/testcase/Batsh/arith.ast index 33513d1..744f9fe 100644 --- a/test/testcase/Batsh/arith.ast +++ b/test/testcase/Batsh/arith.ast @@ -1,505 +1,1286 @@ Program - [ Statement - (Expression - (Call - ( "println" - , [ Literal - (Bool - False - LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 5 }) - LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 5 } - ] - ) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 14 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 } - , Statement - (Expression - (Call - ( "println" - , [ Literal - (Bool - True - LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 24 , lpLength = 4 }) - LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 24 , lpLength = 4 } - ] - ) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 13 }) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 14 }) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 14 } - , Statement - (Expression - (Call - ( "println" - , [ Literal - (Int - 42 - LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 39 , lpLength = 2 }) - LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 39 , lpLength = 2 } - ] - ) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 31 , lpLength = 11 }) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 31 , lpLength = 12 }) - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 31 , lpLength = 12 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Plus - LP { lpLine = 4 , lpColumn = 11 , lpStartByte = 54 , lpLength = 1 } - , Literal - (Int - 1 - LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 52 , lpLength = 1 }) - LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 52 , lpLength = 1 } - , Binary - ( Multiply - LP { lpLine = 4 , lpColumn = 21 , lpStartByte = 64 , lpLength = 1 } - , Binary - ( Plus - LP { lpLine = 4 , lpColumn = 16 , lpStartByte = 59 , lpLength = 1 } - , Literal - (Int - 4 - LP - { lpLine = 4 , lpColumn = 14 , lpStartByte = 57 , lpLength = 1 }) - LP { lpLine = 4 , lpColumn = 14 , lpStartByte = 57 , lpLength = 1 } - , Literal - (Int - 6 - LP - { lpLine = 4 , lpColumn = 18 , lpStartByte = 61 , lpLength = 1 }) - LP { lpLine = 4 , lpColumn = 18 , lpStartByte = 61 , lpLength = 1 } - ) - LP { lpLine = 4 , lpColumn = 14 , lpStartByte = 57 , lpLength = 5 } - , Literal - (Int - 3 - LP - { lpLine = 4 , lpColumn = 23 , lpStartByte = 66 , lpLength = 1 }) - LP { lpLine = 4 , lpColumn = 23 , lpStartByte = 66 , lpLength = 1 } - ) - LP - { lpLine = 4 , lpColumn = 14 , lpStartByte = 57 , lpLength = 10 } - ) - LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 52 , lpLength = 15 } - ] - ) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 44 , lpLength = 24 }) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 44 , lpLength = 25 }) - LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 44 , lpLength = 25 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Minus - LP { lpLine = 5 , lpColumn = 11 , lpStartByte = 80 , lpLength = 1 } - , Literal - (Int - 8 - LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 1 }) - LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 1 } - , Binary - ( Modulo - LP { lpLine = 5 , lpColumn = 15 , lpStartByte = 84 , lpLength = 1 } - , Literal - (Int - 3 - LP - { lpLine = 5 , lpColumn = 13 , lpStartByte = 82 , lpLength = 1 }) - LP { lpLine = 5 , lpColumn = 13 , lpStartByte = 82 , lpLength = 1 } - , Literal - (Int - 2 - LP - { lpLine = 5 , lpColumn = 17 , lpStartByte = 86 , lpLength = 1 }) - LP { lpLine = 5 , lpColumn = 17 , lpStartByte = 86 , lpLength = 1 } - ) - LP { lpLine = 5 , lpColumn = 13 , lpStartByte = 82 , lpLength = 5 } - ) - LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 9 } - ] - ) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 18 }) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 19 }) - LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 19 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Minus - LP - { lpLine = 6 , lpColumn = 12 , lpStartByte = 101 , lpLength = 1 } - , Unary - ( Negate - LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 98 , lpLength = 1 } - , Literal - (Int - 9 - LP - { lpLine = 6 , lpColumn = 10 , lpStartByte = 99 , lpLength = 1 }) - LP { lpLine = 6 , lpColumn = 10 , lpStartByte = 99 , lpLength = 1 } - ) - LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 98 , lpLength = 2 } - , Literal - (Int - 9 - LP - { lpLine = 6 , lpColumn = 14 , lpStartByte = 103 , lpLength = 1 }) - LP - { lpLine = 6 , lpColumn = 14 , lpStartByte = 103 , lpLength = 1 } - ) - LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 98 , lpLength = 6 } - ] - ) - LP - { lpLine = 6 , lpColumn = 1 , lpStartByte = 90 , lpLength = 15 }) - LP - { lpLine = 6 , lpColumn = 1 , lpStartByte = 90 , lpLength = 16 }) - LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 90 , lpLength = 16 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Divide - LP - { lpLine = 7 , lpColumn = 17 , lpStartByte = 123 , lpLength = 1 } - , Binary - ( Plus + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + Bool + { literal_bool = False + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 9 + , lpStartByte = 8 + , lpLength = 5 + } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 5 } + } + ] + , expr_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 14 } + } + , stmt_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 } + } + , toplevel_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + Bool + { literal_bool = True + , literal_annot = + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 24 + , lpLength = 4 + } + } + , expr_annot = + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 24 , lpLength = 4 } + } + ] + , expr_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 13 } + } + , stmt_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 14 } + } + , toplevel_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 14 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + Int + { literal_int = 42 + , literal_annot = + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 39 + , lpLength = 2 + } + } + , expr_annot = + LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 39 , lpLength = 2 } + } + ] + , expr_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 31 , lpLength = 11 } + } + , stmt_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 31 , lpLength = 12 } + } + , toplevel_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 31 , lpLength = 12 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 4 + , lpColumn = 11 + , lpStartByte = 54 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 52 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 52 + , lpLength = 1 + } + } + , expr_right = + Binary + { expr_binOp = + Multiply + { binOp_annot = + LP + { lpLine = 4 + , lpColumn = 21 + , lpStartByte = 64 + , lpLength = 1 + } + } + , expr_left = + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 4 + , lpColumn = 16 + , lpStartByte = 59 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + LP + { lpLine = 4 + , lpColumn = 14 + , lpStartByte = 57 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 14 + , lpStartByte = 57 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 6 + , literal_annot = + LP + { lpLine = 4 + , lpColumn = 18 + , lpStartByte = 61 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 18 + , lpStartByte = 61 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 14 + , lpStartByte = 57 + , lpLength = 5 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 4 + , lpColumn = 23 + , lpStartByte = 66 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 23 + , lpStartByte = 66 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 14 + , lpStartByte = 57 + , lpLength = 10 + } + } + , expr_annot = + LP + { lpLine = 4 , lpColumn = 9 , lpStartByte = 52 , lpLength = 15 } + } + ] + , expr_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 44 , lpLength = 24 } + } + , stmt_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 44 , lpLength = 25 } + } + , toplevel_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 44 , lpLength = 25 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Minus + { binOp_annot = + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 80 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 8 + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 78 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 78 + , lpLength = 1 + } + } + , expr_right = + Binary + { expr_binOp = + Modulo + { binOp_annot = + LP + { lpLine = 5 + , lpColumn = 15 + , lpStartByte = 84 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 13 + , lpStartByte = 82 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 13 + , lpStartByte = 82 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 17 + , lpStartByte = 86 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 17 + , lpStartByte = 86 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 13 + , lpStartByte = 82 + , lpLength = 5 + } + } + , expr_annot = + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 9 } + } + ] + , expr_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 18 } + } + , stmt_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 19 } + } + , toplevel_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 19 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Minus + { binOp_annot = + LP + { lpLine = 6 + , lpColumn = 12 + , lpStartByte = 101 + , lpLength = 1 + } + } + , expr_left = + Unary + { expr_unOp = + Negate + { unOp_annot = + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 98 + , lpLength = 1 + } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 9 + , literal_annot = + LP + { lpLine = 6 + , lpColumn = 10 + , lpStartByte = 99 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 6 + , lpColumn = 10 + , lpStartByte = 99 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 98 + , lpLength = 2 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 9 + , literal_annot = + LP + { lpLine = 6 + , lpColumn = 14 + , lpStartByte = 103 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 6 + , lpColumn = 14 + , lpStartByte = 103 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 98 , lpLength = 6 } + } + ] + , expr_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 90 , lpLength = 15 } + } + , stmt_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 90 , lpLength = 16 } + } + , toplevel_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 90 , lpLength = 16 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Divide + { binOp_annot = + LP + { lpLine = 7 + , lpColumn = 17 + , lpStartByte = 123 + , lpLength = 1 + } + } + , expr_left = + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 7 + , lpColumn = 12 + , lpStartByte = 118 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 116 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 116 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 8 + , literal_annot = + LP + { lpLine = 7 + , lpColumn = 14 + , lpStartByte = 120 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 14 + , lpStartByte = 120 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 116 + , lpLength = 5 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 7 + , lpColumn = 19 + , lpStartByte = 125 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 19 + , lpStartByte = 125 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 116 + , lpLength = 10 + } + } + ] + , expr_annot = LP - { lpLine = 7 , lpColumn = 12 , lpStartByte = 118 , lpLength = 1 } - , Literal - (Int - 2 - LP - { lpLine = 7 , lpColumn = 10 , lpStartByte = 116 , lpLength = 1 }) + { lpLine = 7 , lpColumn = 1 , lpStartByte = 107 , lpLength = 20 } + } + , stmt_annot = + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 107 , lpLength = 21 } + } + , toplevel_annot = + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 107 , lpLength = 21 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + ArithEqual + { binOp_annot = + LP + { lpLine = 8 + , lpColumn = 11 + , lpStartByte = 139 + , lpLength = 3 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 137 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 137 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 15 + , lpStartByte = 143 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 15 + , lpStartByte = 143 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 8 , lpColumn = 9 , lpStartByte = 137 , lpLength = 7 } + } + ] + , expr_annot = LP - { lpLine = 7 , lpColumn = 10 , lpStartByte = 116 , lpLength = 1 } - , Literal - (Int - 8 - LP - { lpLine = 7 , lpColumn = 14 , lpStartByte = 120 , lpLength = 1 }) + { lpLine = 8 , lpColumn = 1 , lpStartByte = 129 , lpLength = 16 } + } + , stmt_annot = + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 129 , lpLength = 17 } + } + , toplevel_annot = + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 129 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + ArithNotEqual + { binOp_annot = + LP + { lpLine = 9 + , lpColumn = 11 + , lpStartByte = 157 + , lpLength = 3 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 6 + , literal_annot = + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 155 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 155 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 8 + , literal_annot = + LP + { lpLine = 9 + , lpColumn = 15 + , lpStartByte = 161 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 9 + , lpColumn = 15 + , lpStartByte = 161 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 9 , lpColumn = 9 , lpStartByte = 155 , lpLength = 7 } + } + ] + , expr_annot = LP - { lpLine = 7 , lpColumn = 14 , lpStartByte = 120 , lpLength = 1 } - ) - LP - { lpLine = 7 , lpColumn = 10 , lpStartByte = 116 , lpLength = 5 } - , Literal - (Int - 3 - LP - { lpLine = 7 , lpColumn = 19 , lpStartByte = 125 , lpLength = 1 }) - LP - { lpLine = 7 , lpColumn = 19 , lpStartByte = 125 , lpLength = 1 } - ) - LP - { lpLine = 7 , lpColumn = 10 , lpStartByte = 116 , lpLength = 10 } - ] - ) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 107 , lpLength = 20 }) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 107 , lpLength = 21 }) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 107 , lpLength = 21 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( ArithEqual - LP - { lpLine = 8 , lpColumn = 11 , lpStartByte = 139 , lpLength = 3 } - , Literal - (Int - 2 - LP - { lpLine = 8 , lpColumn = 9 , lpStartByte = 137 , lpLength = 1 }) - LP { lpLine = 8 , lpColumn = 9 , lpStartByte = 137 , lpLength = 1 } - , Literal - (Int - 2 - LP - { lpLine = 8 , lpColumn = 15 , lpStartByte = 143 , lpLength = 1 }) - LP - { lpLine = 8 , lpColumn = 15 , lpStartByte = 143 , lpLength = 1 } - ) - LP { lpLine = 8 , lpColumn = 9 , lpStartByte = 137 , lpLength = 7 } - ] - ) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 129 , lpLength = 16 }) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 129 , lpLength = 17 }) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 129 , lpLength = 17 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( ArithNotEqual - LP - { lpLine = 9 , lpColumn = 11 , lpStartByte = 157 , lpLength = 3 } - , Literal - (Int - 6 - LP - { lpLine = 9 , lpColumn = 9 , lpStartByte = 155 , lpLength = 1 }) - LP { lpLine = 9 , lpColumn = 9 , lpStartByte = 155 , lpLength = 1 } - , Literal - (Int - 8 - LP - { lpLine = 9 , lpColumn = 15 , lpStartByte = 161 , lpLength = 1 }) - LP - { lpLine = 9 , lpColumn = 15 , lpStartByte = 161 , lpLength = 1 } - ) - LP { lpLine = 9 , lpColumn = 9 , lpStartByte = 155 , lpLength = 7 } - ] - ) - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 147 , lpLength = 16 }) - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 147 , lpLength = 17 }) - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 147 , lpLength = 17 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Greater - LP - { lpLine = 10 , lpColumn = 11 , lpStartByte = 175 , lpLength = 1 } - , Literal - (Int - 3 - LP - { lpLine = 10 , lpColumn = 9 , lpStartByte = 173 , lpLength = 1 }) - LP - { lpLine = 10 , lpColumn = 9 , lpStartByte = 173 , lpLength = 1 } - , Literal - (Int - 2 - LP - { lpLine = 10 , lpColumn = 13 , lpStartByte = 177 , lpLength = 1 }) - LP - { lpLine = 10 , lpColumn = 13 , lpStartByte = 177 , lpLength = 1 } - ) - LP - { lpLine = 10 , lpColumn = 9 , lpStartByte = 173 , lpLength = 5 } - ] - ) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 165 , lpLength = 14 }) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 165 , lpLength = 15 }) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 165 , lpLength = 15 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Less - LP - { lpLine = 11 , lpColumn = 11 , lpStartByte = 191 , lpLength = 1 } - , Literal - (Int - 4 - LP - { lpLine = 11 , lpColumn = 9 , lpStartByte = 189 , lpLength = 1 }) - LP - { lpLine = 11 , lpColumn = 9 , lpStartByte = 189 , lpLength = 1 } - , Literal - (Int - 5 - LP - { lpLine = 11 , lpColumn = 13 , lpStartByte = 193 , lpLength = 1 }) - LP - { lpLine = 11 , lpColumn = 13 , lpStartByte = 193 , lpLength = 1 } - ) - LP - { lpLine = 11 , lpColumn = 9 , lpStartByte = 189 , lpLength = 5 } - ] - ) - LP - { lpLine = 11 , lpColumn = 1 , lpStartByte = 181 , lpLength = 14 }) - LP - { lpLine = 11 , lpColumn = 1 , lpStartByte = 181 , lpLength = 15 }) - LP - { lpLine = 11 , lpColumn = 1 , lpStartByte = 181 , lpLength = 15 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( GreaterEqual - LP - { lpLine = 12 , lpColumn = 11 , lpStartByte = 207 , lpLength = 2 } - , Literal - (Int - 6 - LP - { lpLine = 12 , lpColumn = 9 , lpStartByte = 205 , lpLength = 1 }) - LP - { lpLine = 12 , lpColumn = 9 , lpStartByte = 205 , lpLength = 1 } - , Literal - (Int - 2 - LP - { lpLine = 12 , lpColumn = 14 , lpStartByte = 210 , lpLength = 1 }) - LP - { lpLine = 12 , lpColumn = 14 , lpStartByte = 210 , lpLength = 1 } - ) - LP - { lpLine = 12 , lpColumn = 9 , lpStartByte = 205 , lpLength = 6 } - ] - ) - LP - { lpLine = 12 , lpColumn = 1 , lpStartByte = 197 , lpLength = 15 }) - LP - { lpLine = 12 , lpColumn = 1 , lpStartByte = 197 , lpLength = 16 }) - LP - { lpLine = 12 , lpColumn = 1 , lpStartByte = 197 , lpLength = 16 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( LessEqual - LP - { lpLine = 13 , lpColumn = 12 , lpStartByte = 225 , lpLength = 2 } - , Literal - (Int - 19 - LP - { lpLine = 13 , lpColumn = 9 , lpStartByte = 222 , lpLength = 2 }) - LP - { lpLine = 13 , lpColumn = 9 , lpStartByte = 222 , lpLength = 2 } - , Literal - (Int - 30 - LP - { lpLine = 13 , lpColumn = 15 , lpStartByte = 228 , lpLength = 2 }) - LP - { lpLine = 13 , lpColumn = 15 , lpStartByte = 228 , lpLength = 2 } - ) - LP - { lpLine = 13 , lpColumn = 9 , lpStartByte = 222 , lpLength = 8 } - ] - ) - LP - { lpLine = 13 , lpColumn = 1 , lpStartByte = 214 , lpLength = 17 }) - LP - { lpLine = 13 , lpColumn = 1 , lpStartByte = 214 , lpLength = 18 }) - LP - { lpLine = 13 , lpColumn = 1 , lpStartByte = 214 , lpLength = 18 } - , Statement - (Expression - (Call - ( "println" - , [ Unary - ( Not - LP - { lpLine = 14 , lpColumn = 9 , lpStartByte = 241 , lpLength = 1 } - , Literal - (Bool - True - LP - { lpLine = 14 , lpColumn = 10 , lpStartByte = 242 , lpLength = 4 }) - LP - { lpLine = 14 , lpColumn = 10 , lpStartByte = 242 , lpLength = 4 } - ) - LP - { lpLine = 14 , lpColumn = 9 , lpStartByte = 241 , lpLength = 5 } - ] - ) - LP - { lpLine = 14 , lpColumn = 1 , lpStartByte = 233 , lpLength = 14 }) - LP - { lpLine = 14 , lpColumn = 1 , lpStartByte = 233 , lpLength = 15 }) - LP - { lpLine = 14 , lpColumn = 1 , lpStartByte = 233 , lpLength = 15 } - , Statement - (Expression - (Call - ( "println" - , [ Unary - ( Not - LP - { lpLine = 15 , lpColumn = 9 , lpStartByte = 257 , lpLength = 1 } - , Literal - (Bool - False - LP - { lpLine = 15 , lpColumn = 10 , lpStartByte = 258 , lpLength = 5 }) - LP - { lpLine = 15 , lpColumn = 10 , lpStartByte = 258 , lpLength = 5 } - ) - LP - { lpLine = 15 , lpColumn = 9 , lpStartByte = 257 , lpLength = 6 } - ] - ) - LP - { lpLine = 15 , lpColumn = 1 , lpStartByte = 249 , lpLength = 15 }) - LP - { lpLine = 15 , lpColumn = 1 , lpStartByte = 249 , lpLength = 16 }) - LP - { lpLine = 15 , lpColumn = 1 , lpStartByte = 249 , lpLength = 16 } - , Statement - (Expression - (Call - ( "println" - , [ Unary - ( Not - LP - { lpLine = 16 , lpColumn = 9 , lpStartByte = 274 , lpLength = 1 } - , Binary - ( Minus + { lpLine = 9 , lpColumn = 1 , lpStartByte = 147 , lpLength = 16 } + } + , stmt_annot = + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 147 , lpLength = 17 } + } + , toplevel_annot = + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 147 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Greater + { binOp_annot = + LP + { lpLine = 10 + , lpColumn = 11 + , lpStartByte = 175 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 173 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 173 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 10 + , lpColumn = 13 + , lpStartByte = 177 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 13 + , lpStartByte = 177 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 173 + , lpLength = 5 + } + } + ] + , expr_annot = LP - { lpLine = 16 , lpColumn = 13 , lpStartByte = 278 , lpLength = 1 } - , Literal - (Int - 2 - LP - { lpLine = 16 , lpColumn = 11 , lpStartByte = 276 , lpLength = 1 }) + { lpLine = 10 , lpColumn = 1 , lpStartByte = 165 , lpLength = 14 } + } + , stmt_annot = + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 165 , lpLength = 15 } + } + , toplevel_annot = + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 165 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Less + { binOp_annot = + LP + { lpLine = 11 + , lpColumn = 11 + , lpStartByte = 191 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 189 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 189 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 5 + , literal_annot = + LP + { lpLine = 11 + , lpColumn = 13 + , lpStartByte = 193 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 13 + , lpStartByte = 193 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 189 + , lpLength = 5 + } + } + ] + , expr_annot = LP - { lpLine = 16 , lpColumn = 11 , lpStartByte = 276 , lpLength = 1 } - , Literal - (Int - 1 - LP - { lpLine = 16 , lpColumn = 15 , lpStartByte = 280 , lpLength = 1 }) + { lpLine = 11 , lpColumn = 1 , lpStartByte = 181 , lpLength = 14 } + } + , stmt_annot = + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 181 , lpLength = 15 } + } + , toplevel_annot = + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 181 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + GreaterEqual + { binOp_annot = + LP + { lpLine = 12 + , lpColumn = 11 + , lpStartByte = 207 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 6 + , literal_annot = + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 205 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 205 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 12 + , lpColumn = 14 + , lpStartByte = 210 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 14 + , lpStartByte = 210 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 205 + , lpLength = 6 + } + } + ] + , expr_annot = LP - { lpLine = 16 , lpColumn = 15 , lpStartByte = 280 , lpLength = 1 } - ) - LP - { lpLine = 16 , lpColumn = 11 , lpStartByte = 276 , lpLength = 5 } - ) - LP - { lpLine = 16 , lpColumn = 9 , lpStartByte = 274 , lpLength = 7 } - ] - ) - LP - { lpLine = 16 , lpColumn = 1 , lpStartByte = 266 , lpLength = 17 }) - LP - { lpLine = 16 , lpColumn = 1 , lpStartByte = 266 , lpLength = 18 }) - LP - { lpLine = 16 , lpColumn = 1 , lpStartByte = 266 , lpLength = 18 } - ] - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 284 } + { lpLine = 12 , lpColumn = 1 , lpStartByte = 197 , lpLength = 15 } + } + , stmt_annot = + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 197 , lpLength = 16 } + } + , toplevel_annot = + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 197 , lpLength = 16 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + LessEqual + { binOp_annot = + LP + { lpLine = 13 + , lpColumn = 12 + , lpStartByte = 225 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 19 + , literal_annot = + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 222 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 222 + , lpLength = 2 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 30 + , literal_annot = + LP + { lpLine = 13 + , lpColumn = 15 + , lpStartByte = 228 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 13 + , lpColumn = 15 + , lpStartByte = 228 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 222 + , lpLength = 8 + } + } + ] + , expr_annot = + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 214 , lpLength = 17 } + } + , stmt_annot = + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 214 , lpLength = 18 } + } + , toplevel_annot = + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 214 , lpLength = 18 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Unary + { expr_unOp = + Not + { unOp_annot = + LP + { lpLine = 14 + , lpColumn = 9 + , lpStartByte = 241 + , lpLength = 1 + } + } + , expr_subExpr = + Literal + { expr_literal = + Bool + { literal_bool = True + , literal_annot = + LP + { lpLine = 14 + , lpColumn = 10 + , lpStartByte = 242 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 14 + , lpColumn = 10 + , lpStartByte = 242 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 14 + , lpColumn = 9 + , lpStartByte = 241 + , lpLength = 5 + } + } + ] + , expr_annot = + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 233 , lpLength = 14 } + } + , stmt_annot = + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 233 , lpLength = 15 } + } + , toplevel_annot = + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 233 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Unary + { expr_unOp = + Not + { unOp_annot = + LP + { lpLine = 15 + , lpColumn = 9 + , lpStartByte = 257 + , lpLength = 1 + } + } + , expr_subExpr = + Literal + { expr_literal = + Bool + { literal_bool = False + , literal_annot = + LP + { lpLine = 15 + , lpColumn = 10 + , lpStartByte = 258 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 15 + , lpColumn = 10 + , lpStartByte = 258 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 15 + , lpColumn = 9 + , lpStartByte = 257 + , lpLength = 6 + } + } + ] + , expr_annot = + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 249 , lpLength = 15 } + } + , stmt_annot = + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 249 , lpLength = 16 } + } + , toplevel_annot = + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 249 , lpLength = 16 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Unary + { expr_unOp = + Not + { unOp_annot = + LP + { lpLine = 16 + , lpColumn = 9 + , lpStartByte = 274 + , lpLength = 1 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Minus + { binOp_annot = + LP + { lpLine = 16 + , lpColumn = 13 + , lpStartByte = 278 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 276 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 276 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 16 + , lpColumn = 15 + , lpStartByte = 280 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 16 + , lpColumn = 15 + , lpStartByte = 280 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 276 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 16 + , lpColumn = 9 + , lpStartByte = 274 + , lpLength = 7 + } + } + ] + , expr_annot = + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 266 , lpLength = 17 } + } + , stmt_annot = + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 266 , lpLength = 18 } + } + , toplevel_annot = + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 266 , lpLength = 18 } + } + ] + , program_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 284 } + } diff --git a/test/testcase/Batsh/array.ast b/test/testcase/Batsh/array.ast index b3ce07c..1a13b7d 100644 --- a/test/testcase/Batsh/array.ast +++ b/test/testcase/Batsh/array.ast @@ -1,473 +1,1286 @@ Program - [ Statement - (Expression - (Assign - ( Identifier - "a" - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } - , Literal - (List - [ Literal - (String - "" - LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 2 }) - LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 2 } - , Literal - (String - "y" - LP { lpLine = 1 , lpColumn = 10 , lpStartByte = 9 , lpLength = 3 }) - LP { lpLine = 1 , lpColumn = 10 , lpStartByte = 9 , lpLength = 3 } - , Unary - ( Negate - LP { lpLine = 1 , lpColumn = 15 , lpStartByte = 14 , lpLength = 1 } - , Literal - (Int - 1 - LP - { lpLine = 1 , lpColumn = 16 , lpStartByte = 15 , lpLength = 1 }) - LP { lpLine = 1 , lpColumn = 16 , lpStartByte = 15 , lpLength = 1 } - ) - LP { lpLine = 1 , lpColumn = 15 , lpStartByte = 14 , lpLength = 2 } - , Literal - (Int - 1 + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + List + { literal_list = + [ Literal + { expr_literal = + String + { literal_str = "" + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 6 + , lpStartByte = 5 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 6 + , lpStartByte = 5 + , lpLength = 2 + } + } + , Literal + { expr_literal = + String + { literal_str = "y" + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 10 + , lpStartByte = 9 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 10 + , lpStartByte = 9 + , lpLength = 3 + } + } + , Unary + { expr_unOp = + Negate + { unOp_annot = + LP + { lpLine = 1 + , lpColumn = 15 + , lpStartByte = 14 + , lpLength = 1 + } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 16 + , lpStartByte = 15 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 16 + , lpStartByte = 15 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 15 + , lpStartByte = 14 + , lpLength = 2 + } + } + , Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 19 + , lpStartByte = 18 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 19 + , lpStartByte = 18 + , lpLength = 1 + } + } + ] + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 5 + , lpStartByte = 4 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 5 } + } + , stmt_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 21 } + } + , toplevel_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 21 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 2 + , lpColumn = 1 + , lpStartByte = 22 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + LP + { lpLine = 2 + , lpColumn = 3 + , lpStartByte = 24 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 2 + , lpColumn = 3 + , lpStartByte = 24 + , lpLength = 1 + } + } + , lvalue_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 4 } + } + , expr_subExpr = + Binary + { expr_binOp = + Multiply + { binOp_annot = + LP + { lpLine = 2 + , lpColumn = 10 + , lpStartByte = 31 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 2 + , lpColumn = 8 + , lpStartByte = 29 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 2 + , lpColumn = 8 + , lpStartByte = 29 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 9 + , literal_annot = + LP + { lpLine = 2 + , lpColumn = 12 + , lpStartByte = 33 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 2 + , lpColumn = 12 + , lpStartByte = 33 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 29 , lpLength = 5 } + } + , expr_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 12 } + } + , stmt_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 13 } + } + , toplevel_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 13 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 3 + , lpColumn = 1 + , lpStartByte = 36 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 3 + , lpColumn = 3 + , lpStartByte = 38 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 3 + , lpColumn = 3 + , lpStartByte = 38 + , lpLength = 1 + } + } + , lvalue_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 4 } + } + , expr_subExpr = + Literal + { expr_literal = + String + { literal_str = "abx" + , literal_annot = + LP + { lpLine = 3 + , lpColumn = 8 + , lpStartByte = 43 + , lpLength = 5 + } + } + , expr_annot = + LP { lpLine = 3 , lpColumn = 8 , lpStartByte = 43 , lpLength = 5 } + } + , expr_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 12 } + } + , stmt_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 13 } + } + , toplevel_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 13 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 4 + , lpColumn = 1 + , lpStartByte = 50 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + LP + { lpLine = 4 + , lpColumn = 3 + , lpStartByte = 52 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 3 + , lpStartByte = 52 + , lpLength = 1 + } + } + , lvalue_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 4 } + } + , expr_subExpr = + Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 4 + , lpColumn = 12 + , lpStartByte = 61 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "5" + , literal_annot = + LP + { lpLine = 4 + , lpColumn = 8 + , lpStartByte = 57 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 8 + , lpStartByte = 57 + , lpLength = 3 + } + } + , expr_right = + LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 4 + , lpColumn = 15 + , lpStartByte = 64 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + LP + { lpLine = 4 + , lpColumn = 17 + , lpStartByte = 66 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 17 + , lpStartByte = 66 + , lpLength = 1 + } + } + , lvalue_annot = + LP + { lpLine = 4 + , lpColumn = 15 + , lpStartByte = 64 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 15 + , lpStartByte = 64 + , lpLength = 4 + } + } + , expr_annot = + LP { lpLine = 4 , lpColumn = 8 , lpStartByte = 57 , lpLength = 11 } + } + , expr_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 18 } + } + , stmt_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 19 } + } + , toplevel_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 19 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 78 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 80 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 80 + , lpLength = 1 + } + } + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 78 + , lpLength = 4 + } + } + , expr_annot = + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 4 } + } + , LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 15 + , lpStartByte = 84 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 17 + , lpStartByte = 86 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 17 + , lpStartByte = 86 + , lpLength = 1 + } + } + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 15 + , lpStartByte = 84 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 5 , lpColumn = 15 , lpStartByte = 84 , lpLength = 4 } + } + , LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 21 + , lpStartByte = 90 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 23 + , lpStartByte = 92 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 23 + , lpStartByte = 92 + , lpLength = 1 + } + } + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 21 + , lpStartByte = 90 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 5 , lpColumn = 21 , lpStartByte = 90 , lpLength = 4 } + } + , LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 27 + , lpStartByte = 96 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 29 + , lpStartByte = 98 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 29 + , lpStartByte = 98 + , lpLength = 1 + } + } + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 27 + , lpStartByte = 96 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 5 , lpColumn = 27 , lpStartByte = 96 , lpLength = 4 } + } + , LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 33 + , lpStartByte = 102 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 35 + , lpStartByte = 104 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 35 + , lpStartByte = 104 + , lpLength = 1 + } + } + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 33 + , lpStartByte = 102 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 33 + , lpStartByte = 102 + , lpLength = 4 + } + } + ] + , expr_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 37 } + } + , stmt_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 38 } + } + , toplevel_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 38 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + List + { literal_list = + [ Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 6 + , lpColumn = 6 + , lpStartByte = 114 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 6 + , lpColumn = 6 + , lpStartByte = 114 + , lpLength = 1 + } + } + , Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 117 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 117 + , lpLength = 1 + } + } + , Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 6 + , lpColumn = 12 + , lpStartByte = 120 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 6 + , lpColumn = 12 + , lpStartByte = 120 + , lpLength = 1 + } + } + ] + , literal_annot = + LP + { lpLine = 6 + , lpColumn = 5 + , lpStartByte = 113 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 6 , lpColumn = 5 , lpStartByte = 113 , lpLength = 1 } + } + , expr_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 5 } + } + , stmt_annot = + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 14 } + } + , toplevel_annot = + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 14 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 7 + , lpColumn = 9 + , lpStartByte = 132 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + LP + { lpLine = 7 + , lpColumn = 11 + , lpStartByte = 134 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 11 + , lpStartByte = 134 + , lpLength = 1 + } + } + , lvalue_annot = + LP + { lpLine = 7 + , lpColumn = 9 + , lpStartByte = 132 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 7 , lpColumn = 9 , lpStartByte = 132 , lpLength = 4 } + } + , LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 7 + , lpColumn = 15 + , lpStartByte = 138 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 7 + , lpColumn = 17 + , lpStartByte = 140 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 17 + , lpStartByte = 140 + , lpLength = 1 + } + } + , lvalue_annot = + LP + { lpLine = 7 + , lpColumn = 15 + , lpStartByte = 138 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 15 + , lpStartByte = 138 + , lpLength = 4 + } + } + , LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 7 + , lpColumn = 21 + , lpStartByte = 144 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 7 + , lpColumn = 23 + , lpStartByte = 146 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 23 + , lpStartByte = 146 + , lpLength = 1 + } + } + , lvalue_annot = + LP + { lpLine = 7 + , lpColumn = 21 + , lpStartByte = 144 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 21 + , lpStartByte = 144 + , lpLength = 4 + } + } + ] + , expr_annot = LP - { lpLine = 1 , lpColumn = 19 , lpStartByte = 18 , lpLength = 1 }) - LP { lpLine = 1 , lpColumn = 19 , lpStartByte = 18 , lpLength = 1 } - ] - LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 }) - LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } - ) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 5 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 21 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 21 } - , Statement - (Expression - (Assign - ( ListAccess - ( Identifier - "a" - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 1 } - , Literal - (Int - 0 - LP { lpLine = 2 , lpColumn = 3 , lpStartByte = 24 , lpLength = 1 }) - LP { lpLine = 2 , lpColumn = 3 , lpStartByte = 24 , lpLength = 1 } - ) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 4 } - , Binary - ( Multiply - LP { lpLine = 2 , lpColumn = 10 , lpStartByte = 31 , lpLength = 1 } - , Literal - (Int - 2 - LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 29 , lpLength = 1 }) - LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 29 , lpLength = 1 } - , Literal - (Int - 9 - LP - { lpLine = 2 , lpColumn = 12 , lpStartByte = 33 , lpLength = 1 }) - LP { lpLine = 2 , lpColumn = 12 , lpStartByte = 33 , lpLength = 1 } - ) - LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 29 , lpLength = 5 } - ) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 12 }) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 13 }) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 13 } - , Statement - (Expression - (Assign - ( ListAccess - ( Identifier - "a" - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 1 } - , Literal - (Int - 2 - LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 38 , lpLength = 1 }) - LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 38 , lpLength = 1 } - ) - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 4 } - , Literal - (String - "abx" - LP { lpLine = 3 , lpColumn = 8 , lpStartByte = 43 , lpLength = 5 }) - LP { lpLine = 3 , lpColumn = 8 , lpStartByte = 43 , lpLength = 5 } - ) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 12 }) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 13 }) - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 13 } - , Statement - (Expression - (Assign - ( ListAccess - ( Identifier - "a" - LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 1 } - , Literal - (Int - 4 - LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 52 , lpLength = 1 }) - LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 52 , lpLength = 1 } - ) - LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 4 } - , Binary - ( Concat - LP { lpLine = 4 , lpColumn = 12 , lpStartByte = 61 , lpLength = 2 } - , Literal - (String - "5" - LP { lpLine = 4 , lpColumn = 8 , lpStartByte = 57 , lpLength = 3 }) - LP { lpLine = 4 , lpColumn = 8 , lpStartByte = 57 , lpLength = 3 } - , LeftValue - (ListAccess - ( Identifier - "a" - LP { lpLine = 4 , lpColumn = 15 , lpStartByte = 64 , lpLength = 1 } - , Literal - (Int - 0 - LP - { lpLine = 4 , lpColumn = 17 , lpStartByte = 66 , lpLength = 1 }) - LP { lpLine = 4 , lpColumn = 17 , lpStartByte = 66 , lpLength = 1 } - ) - LP - { lpLine = 4 , lpColumn = 15 , lpStartByte = 64 , lpLength = 4 }) - LP { lpLine = 4 , lpColumn = 15 , lpStartByte = 64 , lpLength = 4 } - ) - LP { lpLine = 4 , lpColumn = 8 , lpStartByte = 57 , lpLength = 11 } - ) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 18 }) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 19 }) - LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 19 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (ListAccess - ( Identifier - "a" - LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 1 } - , Literal - (Int - 0 - LP - { lpLine = 5 , lpColumn = 11 , lpStartByte = 80 , lpLength = 1 }) - LP { lpLine = 5 , lpColumn = 11 , lpStartByte = 80 , lpLength = 1 } - ) - LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 4 }) - LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 78 , lpLength = 4 } - , LeftValue - (ListAccess - ( Identifier - "a" - LP { lpLine = 5 , lpColumn = 15 , lpStartByte = 84 , lpLength = 1 } - , Literal - (Int - 1 - LP - { lpLine = 5 , lpColumn = 17 , lpStartByte = 86 , lpLength = 1 }) - LP { lpLine = 5 , lpColumn = 17 , lpStartByte = 86 , lpLength = 1 } - ) - LP - { lpLine = 5 , lpColumn = 15 , lpStartByte = 84 , lpLength = 4 }) - LP { lpLine = 5 , lpColumn = 15 , lpStartByte = 84 , lpLength = 4 } - , LeftValue - (ListAccess - ( Identifier - "a" - LP { lpLine = 5 , lpColumn = 21 , lpStartByte = 90 , lpLength = 1 } - , Literal - (Int - 2 - LP - { lpLine = 5 , lpColumn = 23 , lpStartByte = 92 , lpLength = 1 }) - LP { lpLine = 5 , lpColumn = 23 , lpStartByte = 92 , lpLength = 1 } - ) - LP - { lpLine = 5 , lpColumn = 21 , lpStartByte = 90 , lpLength = 4 }) - LP { lpLine = 5 , lpColumn = 21 , lpStartByte = 90 , lpLength = 4 } - , LeftValue - (ListAccess - ( Identifier - "a" - LP { lpLine = 5 , lpColumn = 27 , lpStartByte = 96 , lpLength = 1 } - , Literal - (Int - 3 - LP - { lpLine = 5 , lpColumn = 29 , lpStartByte = 98 , lpLength = 1 }) - LP { lpLine = 5 , lpColumn = 29 , lpStartByte = 98 , lpLength = 1 } - ) - LP - { lpLine = 5 , lpColumn = 27 , lpStartByte = 96 , lpLength = 4 }) - LP { lpLine = 5 , lpColumn = 27 , lpStartByte = 96 , lpLength = 4 } - , LeftValue - (ListAccess - ( Identifier - "a" - LP - { lpLine = 5 , lpColumn = 33 , lpStartByte = 102 , lpLength = 1 } - , Literal - (Int - 4 - LP - { lpLine = 5 , lpColumn = 35 , lpStartByte = 104 , lpLength = 1 }) - LP - { lpLine = 5 , lpColumn = 35 , lpStartByte = 104 , lpLength = 1 } - ) - LP - { lpLine = 5 , lpColumn = 33 , lpStartByte = 102 , lpLength = 4 }) - LP - { lpLine = 5 , lpColumn = 33 , lpStartByte = 102 , lpLength = 4 } - ] - ) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 37 }) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 38 }) - LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 38 } - , Statement - (Expression - (Assign - ( Identifier - "a" - LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 1 } - , Literal - (List - [ Literal - (Int - 1 + { lpLine = 7 , lpColumn = 1 , lpStartByte = 124 , lpLength = 25 } + } + , stmt_annot = + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 124 , lpLength = 26 } + } + , toplevel_annot = + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 124 , lpLength = 26 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Multiply + { binOp_annot = + LP + { lpLine = 8 + , lpColumn = 24 + , lpStartByte = 174 + , lpLength = 1 + } + } + , expr_left = + Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 8 + , lpColumn = 15 + , lpStartByte = 165 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "10" + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 10 + , lpStartByte = 160 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 10 + , lpStartByte = 160 + , lpLength = 4 + } + } + , expr_right = + LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 8 + , lpColumn = 18 + , lpStartByte = 168 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 20 + , lpStartByte = 170 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 20 + , lpStartByte = 170 + , lpLength = 1 + } + } + , lvalue_annot = + LP + { lpLine = 8 + , lpColumn = 18 + , lpStartByte = 168 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 18 + , lpStartByte = 168 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 10 + , lpStartByte = 160 + , lpLength = 12 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 26 + , lpStartByte = 176 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 26 + , lpStartByte = 176 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 10 + , lpStartByte = 160 + , lpLength = 17 + } + } + ] + , expr_annot = LP - { lpLine = 6 , lpColumn = 6 , lpStartByte = 114 , lpLength = 1 }) - LP { lpLine = 6 , lpColumn = 6 , lpStartByte = 114 , lpLength = 1 } - , Literal - (Int - 2 + { lpLine = 8 , lpColumn = 1 , lpStartByte = 151 , lpLength = 27 } + } + , stmt_annot = + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 151 , lpLength = 28 } + } + , toplevel_annot = + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 151 , lpLength = 28 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Call + { expr_func = "len" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 9 + , lpColumn = 13 + , lpStartByte = 192 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 9 + , lpColumn = 13 + , lpStartByte = 192 + , lpLength = 1 + } + } + ] + , expr_annot = + LP + { lpLine = 9 , lpColumn = 9 , lpStartByte = 188 , lpLength = 6 } + } + ] + , expr_annot = LP - { lpLine = 6 , lpColumn = 9 , lpStartByte = 117 , lpLength = 1 }) - LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 117 , lpLength = 1 } - , Literal - (Int - 3 + { lpLine = 9 , lpColumn = 1 , lpStartByte = 180 , lpLength = 15 } + } + , stmt_annot = + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 180 , lpLength = 16 } + } + , toplevel_annot = + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 180 , lpLength = 16 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Multiply + { binOp_annot = + LP + { lpLine = 10 + , lpColumn = 16 + , lpStartByte = 212 + , lpLength = 1 + } + } + , expr_left = + Call + { expr_func = "len" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 10 + , lpColumn = 13 + , lpStartByte = 209 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 13 + , lpStartByte = 209 + , lpLength = 1 + } + } + ] + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 205 + , lpLength = 6 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 8 + , literal_annot = + LP + { lpLine = 10 + , lpColumn = 18 + , lpStartByte = 214 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 18 + , lpStartByte = 214 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 205 + , lpLength = 10 + } + } + ] + , expr_annot = LP - { lpLine = 6 , lpColumn = 12 , lpStartByte = 120 , lpLength = 1 }) - LP - { lpLine = 6 , lpColumn = 12 , lpStartByte = 120 , lpLength = 1 } - ] - LP - { lpLine = 6 , lpColumn = 5 , lpStartByte = 113 , lpLength = 1 }) - LP { lpLine = 6 , lpColumn = 5 , lpStartByte = 113 , lpLength = 1 } - ) - LP - { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 5 }) - LP - { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 14 }) - LP - { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 14 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (ListAccess - ( Identifier - "a" - LP { lpLine = 7 , lpColumn = 9 , lpStartByte = 132 , lpLength = 1 } - , Literal - (Int - 0 - LP - { lpLine = 7 , lpColumn = 11 , lpStartByte = 134 , lpLength = 1 }) - LP - { lpLine = 7 , lpColumn = 11 , lpStartByte = 134 , lpLength = 1 } - ) - LP - { lpLine = 7 , lpColumn = 9 , lpStartByte = 132 , lpLength = 4 }) - LP { lpLine = 7 , lpColumn = 9 , lpStartByte = 132 , lpLength = 4 } - , LeftValue - (ListAccess - ( Identifier - "a" - LP - { lpLine = 7 , lpColumn = 15 , lpStartByte = 138 , lpLength = 1 } - , Literal - (Int - 1 - LP - { lpLine = 7 , lpColumn = 17 , lpStartByte = 140 , lpLength = 1 }) - LP - { lpLine = 7 , lpColumn = 17 , lpStartByte = 140 , lpLength = 1 } - ) - LP - { lpLine = 7 , lpColumn = 15 , lpStartByte = 138 , lpLength = 4 }) - LP - { lpLine = 7 , lpColumn = 15 , lpStartByte = 138 , lpLength = 4 } - , LeftValue - (ListAccess - ( Identifier - "a" - LP - { lpLine = 7 , lpColumn = 21 , lpStartByte = 144 , lpLength = 1 } - , Literal - (Int - 2 - LP - { lpLine = 7 , lpColumn = 23 , lpStartByte = 146 , lpLength = 1 }) - LP - { lpLine = 7 , lpColumn = 23 , lpStartByte = 146 , lpLength = 1 } - ) - LP - { lpLine = 7 , lpColumn = 21 , lpStartByte = 144 , lpLength = 4 }) - LP - { lpLine = 7 , lpColumn = 21 , lpStartByte = 144 , lpLength = 4 } - ] - ) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 124 , lpLength = 25 }) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 124 , lpLength = 26 }) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 124 , lpLength = 26 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Multiply - LP - { lpLine = 8 , lpColumn = 24 , lpStartByte = 174 , lpLength = 1 } - , Binary - ( Concat - LP - { lpLine = 8 , lpColumn = 15 , lpStartByte = 165 , lpLength = 2 } - , Literal - (String - "10" - LP - { lpLine = 8 , lpColumn = 10 , lpStartByte = 160 , lpLength = 4 }) - LP - { lpLine = 8 , lpColumn = 10 , lpStartByte = 160 , lpLength = 4 } - , LeftValue - (ListAccess - ( Identifier - "a" - LP - { lpLine = 8 , lpColumn = 18 , lpStartByte = 168 , lpLength = 1 } - , Literal - (Int - 0 - LP - { lpLine = 8 - , lpColumn = 20 - , lpStartByte = 170 - , lpLength = 1 - }) - LP - { lpLine = 8 , lpColumn = 20 , lpStartByte = 170 , lpLength = 1 } - ) - LP - { lpLine = 8 , lpColumn = 18 , lpStartByte = 168 , lpLength = 4 }) - LP - { lpLine = 8 , lpColumn = 18 , lpStartByte = 168 , lpLength = 4 } - ) - LP - { lpLine = 8 , lpColumn = 10 , lpStartByte = 160 , lpLength = 12 } - , Literal - (Int - 2 - LP - { lpLine = 8 , lpColumn = 26 , lpStartByte = 176 , lpLength = 1 }) - LP - { lpLine = 8 , lpColumn = 26 , lpStartByte = 176 , lpLength = 1 } - ) - LP - { lpLine = 8 , lpColumn = 10 , lpStartByte = 160 , lpLength = 17 } - ] - ) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 151 , lpLength = 27 }) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 151 , lpLength = 28 }) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 151 , lpLength = 28 } - , Statement - (Expression - (Call - ( "println" - , [ Call - ( "len" - , [ LeftValue - (Identifier - "a" - LP - { lpLine = 9 , lpColumn = 13 , lpStartByte = 192 , lpLength = 1 }) - LP - { lpLine = 9 , lpColumn = 13 , lpStartByte = 192 , lpLength = 1 } - ] - ) - LP { lpLine = 9 , lpColumn = 9 , lpStartByte = 188 , lpLength = 6 } - ] - ) - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 180 , lpLength = 15 }) - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 180 , lpLength = 16 }) - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 180 , lpLength = 16 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Multiply - LP - { lpLine = 10 , lpColumn = 16 , lpStartByte = 212 , lpLength = 1 } - , Call - ( "len" - , [ LeftValue - (Identifier - "a" - LP - { lpLine = 10 , lpColumn = 13 , lpStartByte = 209 , lpLength = 1 }) - LP - { lpLine = 10 , lpColumn = 13 , lpStartByte = 209 , lpLength = 1 } - ] - ) - LP - { lpLine = 10 , lpColumn = 9 , lpStartByte = 205 , lpLength = 6 } - , Literal - (Int - 8 - LP - { lpLine = 10 , lpColumn = 18 , lpStartByte = 214 , lpLength = 1 }) - LP - { lpLine = 10 , lpColumn = 18 , lpStartByte = 214 , lpLength = 1 } - ) - LP - { lpLine = 10 , lpColumn = 9 , lpStartByte = 205 , lpLength = 10 } - ] - ) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 197 , lpLength = 19 }) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 197 , lpLength = 20 }) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 197 , lpLength = 20 } - , Statement - (Comment - "println([1, 2, 3]);" - LP - { lpLine = 11 , lpColumn = 1 , lpStartByte = 218 , lpLength = 21 }) - LP - { lpLine = 11 , lpColumn = 1 , lpStartByte = 218 , lpLength = 21 } - ] - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 239 } + { lpLine = 10 , lpColumn = 1 , lpStartByte = 197 , lpLength = 19 } + } + , stmt_annot = + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 197 , lpLength = 20 } + } + , toplevel_annot = + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 197 , lpLength = 20 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = "println([1, 2, 3]);" + , stmt_annot = + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 218 , lpLength = 21 } + } + , toplevel_annot = + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 218 , lpLength = 21 } + } + ] + , program_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 239 } + } diff --git a/test/testcase/Batsh/assignment.ast b/test/testcase/Batsh/assignment.ast index eb84f6f..ad5d184 100644 --- a/test/testcase/Batsh/assignment.ast +++ b/test/testcase/Batsh/assignment.ast @@ -1,207 +1,528 @@ Program - [ Statement - (Expression - (Assign - ( Identifier - "a" - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } - , Binary - ( Concat - LP { lpLine = 1 , lpColumn = 15 , lpStartByte = 14 , lpLength = 2 } - , Literal - (String - "Value: " - LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 9 }) - LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 9 } - , Binary - ( Plus - LP { lpLine = 1 , lpColumn = 20 , lpStartByte = 19 , lpLength = 1 } - , Literal - (Int - 1 - LP - { lpLine = 1 , lpColumn = 18 , lpStartByte = 17 , lpLength = 1 }) - LP { lpLine = 1 , lpColumn = 18 , lpStartByte = 17 , lpLength = 1 } - , Binary - ( Multiply - LP { lpLine = 1 , lpColumn = 30 , lpStartByte = 29 , lpLength = 1 } - , Binary - ( Plus - LP { lpLine = 1 , lpColumn = 25 , lpStartByte = 24 , lpLength = 1 } - , Literal - (Int - 4 - LP - { lpLine = 1 - , lpColumn = 23 - , lpStartByte = 22 - , lpLength = 1 - }) - LP { lpLine = 1 , lpColumn = 23 , lpStartByte = 22 , lpLength = 1 } - , Literal - (Int - 6 - LP - { lpLine = 1 - , lpColumn = 27 - , lpStartByte = 26 - , lpLength = 1 - }) - LP { lpLine = 1 , lpColumn = 27 , lpStartByte = 26 , lpLength = 1 } - ) - LP { lpLine = 1 , lpColumn = 23 , lpStartByte = 22 , lpLength = 5 } - , Literal - (Int - 3 - LP - { lpLine = 1 , lpColumn = 32 , lpStartByte = 31 , lpLength = 1 }) - LP { lpLine = 1 , lpColumn = 32 , lpStartByte = 31 , lpLength = 1 } - ) - LP - { lpLine = 1 , lpColumn = 23 , lpStartByte = 22 , lpLength = 10 } - ) + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } + } + , expr_subExpr = + Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 1 + , lpColumn = 15 + , lpStartByte = 14 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "Value: " + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 5 + , lpStartByte = 4 + , lpLength = 9 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 5 + , lpStartByte = 4 + , lpLength = 9 + } + } + , expr_right = + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 1 + , lpColumn = 20 + , lpStartByte = 19 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 18 + , lpStartByte = 17 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 18 + , lpStartByte = 17 + , lpLength = 1 + } + } + , expr_right = + Binary + { expr_binOp = + Multiply + { binOp_annot = + LP + { lpLine = 1 + , lpColumn = 30 + , lpStartByte = 29 + , lpLength = 1 + } + } + , expr_left = + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 1 + , lpColumn = 25 + , lpStartByte = 24 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 23 + , lpStartByte = 22 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 23 + , lpStartByte = 22 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 6 + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 27 + , lpStartByte = 26 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 27 + , lpStartByte = 26 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 23 + , lpStartByte = 22 + , lpLength = 5 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 32 + , lpStartByte = 31 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 32 + , lpStartByte = 31 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 23 + , lpStartByte = 22 + , lpLength = 10 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 18 + , lpStartByte = 17 + , lpLength = 15 + } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 28 } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 32 } + } + , stmt_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } + } + , toplevel_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 42 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 42 , lpLength = 1 } + } + ] + , expr_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 34 , lpLength = 10 } + } + , stmt_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 34 , lpLength = 11 } + } + , toplevel_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 34 , lpLength = 11 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "b" + , lvalue_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 1 } + } + , expr_subExpr = + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 3 + , lpColumn = 7 + , lpStartByte = 52 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 3 + , lpColumn = 5 + , lpStartByte = 50 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 3 + , lpColumn = 5 + , lpStartByte = 50 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 54 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 54 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 50 , lpLength = 5 } + } + , expr_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 9 } + } + , stmt_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 10 } + } + , toplevel_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 10 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "b" + , lvalue_annot = + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 65 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 65 , lpLength = 1 } + } + ] + , expr_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 57 , lpLength = 10 } + } + , stmt_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 57 , lpLength = 11 } + } + , toplevel_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 57 , lpLength = 11 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "c" + , lvalue_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 1 } + } + , expr_subExpr = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 5 + , lpStartByte = 73 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 5 , lpColumn = 5 , lpStartByte = 73 , lpLength = 1 } + } + , expr_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 5 } + } + , stmt_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 6 } + } + , toplevel_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "c" + , lvalue_annot = + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 84 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 84 , lpLength = 1 } + } + ] + , expr_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 76 , lpLength = 10 } + } + , stmt_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 76 , lpLength = 11 } + } + , toplevel_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 76 , lpLength = 11 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "d" + , lvalue_annot = + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 1 } + } + , expr_subExpr = + Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 7 + , lpColumn = 7 + , lpStartByte = 94 + , lpLength = 2 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "b" + , lvalue_annot = + LP + { lpLine = 7 + , lpColumn = 5 + , lpStartByte = 92 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 5 + , lpStartByte = 92 + , lpLength = 1 + } + } + , expr_right = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "c" + , lvalue_annot = + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 97 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 97 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 7 , lpColumn = 5 , lpStartByte = 92 , lpLength = 6 } + } + , expr_annot = + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 10 } + } + , stmt_annot = + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 11 } + } + , toplevel_annot = + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 11 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "d" + , lvalue_annot = + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 108 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 8 , lpColumn = 9 , lpStartByte = 108 , lpLength = 1 } + } + ] + , expr_annot = + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 100 , lpLength = 10 } + } + , stmt_annot = LP - { lpLine = 1 , lpColumn = 18 , lpStartByte = 17 , lpLength = 15 } - ) - LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 28 } - ) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 32 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "a" - LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 42 , lpLength = 1 }) - LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 42 , lpLength = 1 } - ] - ) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 34 , lpLength = 10 }) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 34 , lpLength = 11 }) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 34 , lpLength = 11 } - , Statement - (Expression - (Assign - ( Identifier - "b" - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 1 } - , Binary - ( Plus - LP { lpLine = 3 , lpColumn = 7 , lpStartByte = 52 , lpLength = 1 } - , Literal - (Int - 3 - LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 50 , lpLength = 1 }) - LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 50 , lpLength = 1 } - , Literal - (Int - 4 - LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 54 , lpLength = 1 }) - LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 54 , lpLength = 1 } - ) - LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 50 , lpLength = 5 } - ) - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 9 }) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 10 }) - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 10 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "b" - LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 65 , lpLength = 1 }) - LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 65 , lpLength = 1 } - ] - ) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 57 , lpLength = 10 }) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 57 , lpLength = 11 }) - LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 57 , lpLength = 11 } - , Statement - (Expression - (Assign - ( Identifier - "c" - LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 1 } - , LeftValue - (Identifier - "a" - LP { lpLine = 5 , lpColumn = 5 , lpStartByte = 73 , lpLength = 1 }) - LP { lpLine = 5 , lpColumn = 5 , lpStartByte = 73 , lpLength = 1 } - ) - LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 5 }) - LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 6 }) - LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 6 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "c" - LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 84 , lpLength = 1 }) - LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 84 , lpLength = 1 } - ] - ) - LP - { lpLine = 6 , lpColumn = 1 , lpStartByte = 76 , lpLength = 10 }) - LP - { lpLine = 6 , lpColumn = 1 , lpStartByte = 76 , lpLength = 11 }) - LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 76 , lpLength = 11 } - , Statement - (Expression - (Assign - ( Identifier - "d" - LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 1 } - , Binary - ( Concat - LP { lpLine = 7 , lpColumn = 7 , lpStartByte = 94 , lpLength = 2 } - , LeftValue - (Identifier - "b" - LP { lpLine = 7 , lpColumn = 5 , lpStartByte = 92 , lpLength = 1 }) - LP { lpLine = 7 , lpColumn = 5 , lpStartByte = 92 , lpLength = 1 } - , LeftValue - (Identifier - "c" - LP - { lpLine = 7 , lpColumn = 10 , lpStartByte = 97 , lpLength = 1 }) - LP { lpLine = 7 , lpColumn = 10 , lpStartByte = 97 , lpLength = 1 } - ) - LP { lpLine = 7 , lpColumn = 5 , lpStartByte = 92 , lpLength = 6 } - ) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 10 }) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 11 }) - LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 11 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "d" - LP - { lpLine = 8 , lpColumn = 9 , lpStartByte = 108 , lpLength = 1 }) - LP { lpLine = 8 , lpColumn = 9 , lpStartByte = 108 , lpLength = 1 } - ] - ) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 100 , lpLength = 10 }) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 100 , lpLength = 11 }) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 100 , lpLength = 11 } - ] - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 111 } + { lpLine = 8 , lpColumn = 1 , lpStartByte = 100 , lpLength = 11 } + } + , toplevel_annot = + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 100 , lpLength = 11 } + } + ] + , program_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 111 } + } diff --git a/test/testcase/Batsh/block.ast b/test/testcase/Batsh/block.ast index cdd56ab..a79ad21 100644 --- a/test/testcase/Batsh/block.ast +++ b/test/testcase/Batsh/block.ast @@ -1,103 +1,225 @@ Program - [ Statement - (Comment - "Level 0 Start" - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 } - , Statement - (Expression - (Call - ( "println" - , [ Literal - (String - "Hello" - LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 24 , lpLength = 7 }) - LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 24 , lpLength = 7 } - ] - ) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 16 }) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 17 }) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 17 } - , Statement - (Block - [ Comment - "Level 1 Start" - LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 38 , lpLength = 15 } - , Expression - (Call - ( "println" - , [ Literal - (String - "Lo" - LP - { lpLine = 5 , lpColumn = 11 , lpStartByte = 64 , lpLength = 4 }) - LP { lpLine = 5 , lpColumn = 11 , lpStartByte = 64 , lpLength = 4 } - ] - ) - LP - { lpLine = 5 , lpColumn = 3 , lpStartByte = 56 , lpLength = 13 }) - LP { lpLine = 5 , lpColumn = 3 , lpStartByte = 56 , lpLength = 14 } - , Block - [ Comment - "Level 2 Start" - LP { lpLine = 7 , lpColumn = 5 , lpStartByte = 79 , lpLength = 15 } - , Expression - (Call - ( "println" - , [ Literal - (String - "and behold" - LP - { lpLine = 8 , lpColumn = 13 , lpStartByte = 107 , lpLength = 12 }) + { program_topls = + [ Statement + { toplevel_stmt = + Comment + { stmt_comment = "Level 0 Start" + , stmt_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 } + } + , toplevel_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Hello" + , literal_annot = + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 24 + , lpLength = 7 + } + } + , expr_annot = + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 24 , lpLength = 7 } + } + ] + , expr_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 16 } + } + , stmt_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 17 } + } + , toplevel_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Block + { stmt_stmts = + [ Comment + { stmt_comment = "Level 1 Start" + , stmt_annot = + LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 38 , lpLength = 15 } + } + , Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Lo" + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 64 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 64 + , lpLength = 4 + } + } + ] + , expr_annot = + LP + { lpLine = 5 , lpColumn = 3 , lpStartByte = 56 , lpLength = 13 } + } + , stmt_annot = + LP { lpLine = 5 , lpColumn = 3 , lpStartByte = 56 , lpLength = 14 } + } + , Block + { stmt_stmts = + [ Comment + { stmt_comment = "Level 2 Start" + , stmt_annot = + LP + { lpLine = 7 + , lpColumn = 5 + , lpStartByte = 79 + , lpLength = 15 + } + } + , Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "and behold" + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 13 + , lpStartByte = 107 + , lpLength = 12 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 13 + , lpStartByte = 107 + , lpLength = 12 + } + } + ] + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 5 + , lpStartByte = 99 + , lpLength = 21 + } + } + , stmt_annot = + LP + { lpLine = 8 + , lpColumn = 5 + , lpStartByte = 99 + , lpLength = 22 + } + } + , Comment + { stmt_comment = "Level 2 End" + , stmt_annot = + LP + { lpLine = 9 + , lpColumn = 5 + , lpStartByte = 126 + , lpLength = 13 + } + } + ] + , stmt_annot = + LP { lpLine = 6 , lpColumn = 3 , lpStartByte = 73 , lpLength = 70 } + } + , Comment + { stmt_comment = "Level 1 End" + , stmt_annot = + LP + { lpLine = 11 , lpColumn = 3 , lpStartByte = 146 , lpLength = 13 } + } + ] + , stmt_annot = + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 34 , lpLength = 127 } + } + , toplevel_annot = + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 34 , lpLength = 127 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "End" + , literal_annot = + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 170 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 170 + , lpLength = 5 + } + } + ] + , expr_annot = LP - { lpLine = 8 , lpColumn = 13 , lpStartByte = 107 , lpLength = 12 } - ] - ) + { lpLine = 13 , lpColumn = 1 , lpStartByte = 162 , lpLength = 14 } + } + , stmt_annot = + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 162 , lpLength = 15 } + } + , toplevel_annot = + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 162 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = "Level 0 End" + , stmt_annot = LP - { lpLine = 8 , lpColumn = 5 , lpStartByte = 99 , lpLength = 21 }) - LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 99 , lpLength = 22 } - , Comment - "Level 2 End" - LP - { lpLine = 9 , lpColumn = 5 , lpStartByte = 126 , lpLength = 13 } - ] - LP { lpLine = 6 , lpColumn = 3 , lpStartByte = 73 , lpLength = 70 } - , Comment - "Level 1 End" - LP - { lpLine = 11 , lpColumn = 3 , lpStartByte = 146 , lpLength = 13 } - ] - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 34 , lpLength = 127 }) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 34 , lpLength = 127 } - , Statement - (Expression - (Call - ( "println" - , [ Literal - (String - "End" - LP - { lpLine = 13 , lpColumn = 9 , lpStartByte = 170 , lpLength = 5 }) - LP - { lpLine = 13 , lpColumn = 9 , lpStartByte = 170 , lpLength = 5 } - ] - ) - LP - { lpLine = 13 , lpColumn = 1 , lpStartByte = 162 , lpLength = 14 }) - LP - { lpLine = 13 , lpColumn = 1 , lpStartByte = 162 , lpLength = 15 }) - LP - { lpLine = 13 , lpColumn = 1 , lpStartByte = 162 , lpLength = 15 } - , Statement - (Comment - "Level 0 End" - LP - { lpLine = 14 , lpColumn = 1 , lpStartByte = 178 , lpLength = 13 }) - LP - { lpLine = 14 , lpColumn = 1 , lpStartByte = 178 , lpLength = 13 } - ] - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 191 } + { lpLine = 14 , lpColumn = 1 , lpStartByte = 178 , lpLength = 13 } + } + , toplevel_annot = + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 178 , lpLength = 13 } + } + ] + , program_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 191 } + } diff --git a/test/testcase/Batsh/command.ast b/test/testcase/Batsh/command.ast index df8b79d..7c36c18 100644 --- a/test/testcase/Batsh/command.ast +++ b/test/testcase/Batsh/command.ast @@ -1,118 +1,272 @@ Program - [ Statement - (Expression - (Call - ( "call" - , [ Literal - (String - "println" - LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 9 }) - LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 9 } - , Literal - (String - "Println Called" - LP - { lpLine = 1 , lpColumn = 17 , lpStartByte = 16 , lpLength = 16 }) - LP - { lpLine = 1 , lpColumn = 17 , lpStartByte = 16 , lpLength = 16 } - ] - ) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 34 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 34 } - , Statement - (Expression - (Assign - ( Identifier - "cmd" - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 3 } - , Binary - ( Concat - LP { lpLine = 2 , lpColumn = 12 , lpStartByte = 46 , lpLength = 2 } - , Literal - (String - "ec" - LP { lpLine = 2 , lpColumn = 7 , lpStartByte = 41 , lpLength = 4 }) - LP { lpLine = 2 , lpColumn = 7 , lpStartByte = 41 , lpLength = 4 } - , Literal - (String - "ho" - LP - { lpLine = 2 , lpColumn = 15 , lpStartByte = 49 , lpLength = 4 }) - LP { lpLine = 2 , lpColumn = 15 , lpStartByte = 49 , lpLength = 4 } - ) - LP { lpLine = 2 , lpColumn = 7 , lpStartByte = 41 , lpLength = 12 } - ) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 18 }) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 19 }) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 19 } - , Statement - (Expression - (Call - ( "call" - , [ LeftValue - (Identifier - "cmd" - LP { lpLine = 3 , lpColumn = 6 , lpStartByte = 60 , lpLength = 3 }) - LP { lpLine = 3 , lpColumn = 6 , lpStartByte = 60 , lpLength = 3 } - , Literal - (String - "Echo Called" - LP - { lpLine = 3 , lpColumn = 11 , lpStartByte = 65 , lpLength = 13 }) - LP - { lpLine = 3 , lpColumn = 11 , lpStartByte = 65 , lpLength = 13 } - ] - ) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 55 , lpLength = 24 }) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 55 , lpLength = 25 }) - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 55 , lpLength = 25 } - , Statement - (Expression - (Assign - ( Identifier - "retval" - LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 6 } - , Call - ( "echo" - , [ Literal - (String - "Value 100%" - LP - { lpLine = 4 , lpColumn = 15 , lpStartByte = 95 , lpLength = 12 }) - LP - { lpLine = 4 , lpColumn = 15 , lpStartByte = 95 , lpLength = 12 } - ] - ) - LP - { lpLine = 4 , lpColumn = 10 , lpStartByte = 90 , lpLength = 18 } - ) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 27 }) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 28 }) - LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 28 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "retval" - LP - { lpLine = 5 , lpColumn = 9 , lpStartByte = 118 , lpLength = 6 }) - LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 118 , lpLength = 6 } - ] - ) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 110 , lpLength = 15 }) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 110 , lpLength = 16 }) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 110 , lpLength = 16 } - ] - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 126 } + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "call" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "println" + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 6 + , lpStartByte = 5 + , lpLength = 9 + } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 9 } + } + , Literal + { expr_literal = + String + { literal_str = "Println Called" + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 17 + , lpStartByte = 16 + , lpLength = 16 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 17 + , lpStartByte = 16 + , lpLength = 16 + } + } + ] + , expr_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } + } + , stmt_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 34 } + } + , toplevel_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 34 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "cmd" + , lvalue_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 3 } + } + , expr_subExpr = + Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 2 + , lpColumn = 12 + , lpStartByte = 46 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "ec" + , literal_annot = + LP + { lpLine = 2 + , lpColumn = 7 + , lpStartByte = 41 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 2 + , lpColumn = 7 + , lpStartByte = 41 + , lpLength = 4 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "ho" + , literal_annot = + LP + { lpLine = 2 + , lpColumn = 15 + , lpStartByte = 49 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 2 + , lpColumn = 15 + , lpStartByte = 49 + , lpLength = 4 + } + } + , expr_annot = + LP { lpLine = 2 , lpColumn = 7 , lpStartByte = 41 , lpLength = 12 } + } + , expr_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 18 } + } + , stmt_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 19 } + } + , toplevel_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 19 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "call" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "cmd" + , lvalue_annot = + LP + { lpLine = 3 + , lpColumn = 6 + , lpStartByte = 60 + , lpLength = 3 + } + } + , expr_annot = + LP { lpLine = 3 , lpColumn = 6 , lpStartByte = 60 , lpLength = 3 } + } + , Literal + { expr_literal = + String + { literal_str = "Echo Called" + , literal_annot = + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 65 + , lpLength = 13 + } + } + , expr_annot = + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 65 + , lpLength = 13 + } + } + ] + , expr_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 55 , lpLength = 24 } + } + , stmt_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 55 , lpLength = 25 } + } + , toplevel_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 55 , lpLength = 25 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "retval" + , lvalue_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 6 } + } + , expr_subExpr = + Call + { expr_func = "echo" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Value 100%" + , literal_annot = + LP + { lpLine = 4 + , lpColumn = 15 + , lpStartByte = 95 + , lpLength = 12 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 15 + , lpStartByte = 95 + , lpLength = 12 + } + } + ] + , expr_annot = + LP + { lpLine = 4 , lpColumn = 10 , lpStartByte = 90 , lpLength = 18 } + } + , expr_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 27 } + } + , stmt_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 28 } + } + , toplevel_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 28 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "retval" + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 118 + , lpLength = 6 + } + } + , expr_annot = + LP + { lpLine = 5 , lpColumn = 9 , lpStartByte = 118 , lpLength = 6 } + } + ] + , expr_annot = + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 110 , lpLength = 15 } + } + , stmt_annot = + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 110 , lpLength = 16 } + } + , toplevel_annot = + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 110 , lpLength = 16 } + } + ] + , program_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 126 } + } diff --git a/test/testcase/Batsh/comment.ast b/test/testcase/Batsh/comment.ast index e92b33c..6f15eac 100644 --- a/test/testcase/Batsh/comment.ast +++ b/test/testcase/Batsh/comment.ast @@ -1,77 +1,181 @@ Program - [ Statement - (Expression - (Assign - ( Identifier - "a" - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } - , Literal - (Int - 3 - LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 }) - LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } - ) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 5 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 } - , Statement - (Comment - " This is comment 1" - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 20 }) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 20 } - , Statement - (Expression - (Assign - ( Identifier - "a" - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 1 } - , Binary - ( Multiply - LP { lpLine = 3 , lpColumn = 7 , lpStartByte = 34 , lpLength = 1 } - , LeftValue - (Identifier - "a" - LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 32 , lpLength = 1 }) - LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 32 , lpLength = 1 } - , Literal - (Int - 5 - LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 36 , lpLength = 1 }) - LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 36 , lpLength = 1 } - ) - LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 32 , lpLength = 5 } - ) - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 9 }) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 10 }) - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 10 } - , Statement - (Comment - " This is comment 2" - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 39 , lpLength = 20 }) - LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 39 , lpLength = 20 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "a" - LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 68 , lpLength = 1 }) - LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 68 , lpLength = 1 } - ] - ) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 60 , lpLength = 10 }) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 60 , lpLength = 11 }) - LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 60 , lpLength = 11 } - , Statement - (Comment - "This is comment 3" - LP - { lpLine = 6 , lpColumn = 1 , lpStartByte = 72 , lpLength = 19 }) - LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 72 , lpLength = 19 } - ] - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 91 } + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 5 + , lpStartByte = 4 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 5 } + } + , stmt_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 } + } + , toplevel_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " This is comment 1" + , stmt_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 20 } + } + , toplevel_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 20 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 1 } + } + , expr_subExpr = + Binary + { expr_binOp = + Multiply + { binOp_annot = + LP + { lpLine = 3 + , lpColumn = 7 + , lpStartByte = 34 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 3 + , lpColumn = 5 + , lpStartByte = 32 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 3 + , lpColumn = 5 + , lpStartByte = 32 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 5 + , literal_annot = + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 36 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 36 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 32 , lpLength = 5 } + } + , expr_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 9 } + } + , stmt_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 10 } + } + , toplevel_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 10 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " This is comment 2" + , stmt_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 39 , lpLength = 20 } + } + , toplevel_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 39 , lpLength = 20 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 68 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 68 , lpLength = 1 } + } + ] + , expr_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 60 , lpLength = 10 } + } + , stmt_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 60 , lpLength = 11 } + } + , toplevel_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 60 , lpLength = 11 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = "This is comment 3" + , stmt_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 72 , lpLength = 19 } + } + , toplevel_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 72 , lpLength = 19 } + } + ] + , program_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 91 } + } diff --git a/test/testcase/Batsh/exists.ast b/test/testcase/Batsh/exists.ast index 3b7abfc..0f69ef7 100644 --- a/test/testcase/Batsh/exists.ast +++ b/test/testcase/Batsh/exists.ast @@ -1,154 +1,342 @@ Program - [ Statement - (Expression - (Assign - ( Identifier - "ex" - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 2 } - , Call - ( "exists" - , [ Literal - (String - "Makefile" - LP - { lpLine = 1 , lpColumn = 13 , lpStartByte = 12 , lpLength = 10 }) - LP - { lpLine = 1 , lpColumn = 13 , lpStartByte = 12 , lpLength = 10 } - ] - ) - LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 18 } - ) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 23 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 24 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 24 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "ex" - LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 33 , lpLength = 2 }) - LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 33 , lpLength = 2 } - ] - ) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 25 , lpLength = 11 }) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 25 , lpLength = 12 }) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 25 , lpLength = 12 } - , Statement - (Expression - (Call - ( "exists" - , [ Literal - (String - "Makefile" - LP - { lpLine = 3 , lpColumn = 8 , lpStartByte = 45 , lpLength = 10 }) - LP { lpLine = 3 , lpColumn = 8 , lpStartByte = 45 , lpLength = 10 } - ] - ) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 18 }) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 19 }) - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 19 } - , Statement - (If - ( Call - ( "exists" - , [ Literal - (String - "Makefile" - LP - { lpLine = 4 , lpColumn = 12 , lpStartByte = 69 , lpLength = 10 }) - LP - { lpLine = 4 , lpColumn = 12 , lpStartByte = 69 , lpLength = 10 } - ] - ) - LP { lpLine = 4 , lpColumn = 5 , lpStartByte = 62 , lpLength = 18 } - , Block - [ Expression - (Call - ( "println" - , [ Literal - (String - "Yes" - LP - { lpLine = 5 , lpColumn = 11 , lpStartByte = 94 , lpLength = 5 }) - LP { lpLine = 5 , lpColumn = 11 , lpStartByte = 94 , lpLength = 5 } - ] - ) - LP - { lpLine = 5 , lpColumn = 3 , lpStartByte = 86 , lpLength = 14 }) - LP { lpLine = 5 , lpColumn = 3 , lpStartByte = 86 , lpLength = 15 } - ] - LP - { lpLine = 4 , lpColumn = 25 , lpStartByte = 82 , lpLength = 21 } - ) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 58 , lpLength = 45 }) - LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 58 , lpLength = 45 } - , Statement - (IfElse - ( Call - ( "exists" - , [ Literal - (String - "none" - LP - { lpLine = 7 , lpColumn = 12 , lpStartByte = 115 , lpLength = 6 }) - LP - { lpLine = 7 , lpColumn = 12 , lpStartByte = 115 , lpLength = 6 } - ] - ) - LP - { lpLine = 7 , lpColumn = 5 , lpStartByte = 108 , lpLength = 14 } - , Block - [ Expression - (Call - ( "println" - , [ Literal - (String - "Impossible" - LP - { lpLine = 8 , lpColumn = 11 , lpStartByte = 136 , lpLength = 12 }) + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "ex" + , lvalue_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 2 } + } + , expr_subExpr = + Call + { expr_func = "exists" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Makefile" + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 13 + , lpStartByte = 12 + , lpLength = 10 + } + } + , expr_annot = + LP + { lpLine = 1 + , lpColumn = 13 + , lpStartByte = 12 + , lpLength = 10 + } + } + ] + , expr_annot = + LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 18 } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 23 } + } + , stmt_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 24 } + } + , toplevel_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 24 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "ex" + , lvalue_annot = + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 33 + , lpLength = 2 + } + } + , expr_annot = + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 33 , lpLength = 2 } + } + ] + , expr_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 25 , lpLength = 11 } + } + , stmt_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 25 , lpLength = 12 } + } + , toplevel_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 25 , lpLength = 12 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "exists" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Makefile" + , literal_annot = + LP + { lpLine = 3 + , lpColumn = 8 + , lpStartByte = 45 + , lpLength = 10 + } + } + , expr_annot = + LP + { lpLine = 3 , lpColumn = 8 , lpStartByte = 45 , lpLength = 10 } + } + ] + , expr_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 18 } + } + , stmt_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 19 } + } + , toplevel_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 19 } + } + , Statement + { toplevel_stmt = + If + { stmt_expr = + Call + { expr_func = "exists" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Makefile" + , literal_annot = + LP + { lpLine = 4 + , lpColumn = 12 + , lpStartByte = 69 + , lpLength = 10 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 12 + , lpStartByte = 69 + , lpLength = 10 + } + } + ] + , expr_annot = + LP { lpLine = 4 , lpColumn = 5 , lpStartByte = 62 , lpLength = 18 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Yes" + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 94 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 94 + , lpLength = 5 + } + } + ] + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 3 + , lpStartByte = 86 + , lpLength = 14 + } + } + , stmt_annot = + LP + { lpLine = 5 , lpColumn = 3 , lpStartByte = 86 , lpLength = 15 } + } + ] + , stmt_annot = LP - { lpLine = 8 , lpColumn = 11 , lpStartByte = 136 , lpLength = 12 } - ] - ) - LP - { lpLine = 8 , lpColumn = 3 , lpStartByte = 128 , lpLength = 21 }) - LP - { lpLine = 8 , lpColumn = 3 , lpStartByte = 128 , lpLength = 22 } - ] - LP - { lpLine = 7 , lpColumn = 21 , lpStartByte = 124 , lpLength = 28 } - , Block - [ Expression - (Call - ( "println" - , [ Literal - (String - "No" - LP - { lpLine = 10 , lpColumn = 11 , lpStartByte = 170 , lpLength = 4 }) + { lpLine = 4 , lpColumn = 25 , lpStartByte = 82 , lpLength = 21 } + } + , stmt_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 58 , lpLength = 45 } + } + , toplevel_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 58 , lpLength = 45 } + } + , Statement + { toplevel_stmt = + IfElse + { stmt_expr = + Call + { expr_func = "exists" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "none" + , literal_annot = + LP + { lpLine = 7 + , lpColumn = 12 + , lpStartByte = 115 + , lpLength = 6 + } + } + , expr_annot = + LP + { lpLine = 7 + , lpColumn = 12 + , lpStartByte = 115 + , lpLength = 6 + } + } + ] + , expr_annot = + LP + { lpLine = 7 , lpColumn = 5 , lpStartByte = 108 , lpLength = 14 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Impossible" + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 11 + , lpStartByte = 136 + , lpLength = 12 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 11 + , lpStartByte = 136 + , lpLength = 12 + } + } + ] + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 3 + , lpStartByte = 128 + , lpLength = 21 + } + } + , stmt_annot = + LP + { lpLine = 8 + , lpColumn = 3 + , lpStartByte = 128 + , lpLength = 22 + } + } + ] + , stmt_annot = + LP + { lpLine = 7 , lpColumn = 21 , lpStartByte = 124 , lpLength = 28 } + } + , stmt_else = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "No" + , literal_annot = + LP + { lpLine = 10 + , lpColumn = 11 + , lpStartByte = 170 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 11 + , lpStartByte = 170 + , lpLength = 4 + } + } + ] + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 3 + , lpStartByte = 162 + , lpLength = 13 + } + } + , stmt_annot = + LP + { lpLine = 10 + , lpColumn = 3 + , lpStartByte = 162 + , lpLength = 14 + } + } + ] + , stmt_annot = LP - { lpLine = 10 , lpColumn = 11 , lpStartByte = 170 , lpLength = 4 } - ] - ) + { lpLine = 9 , lpColumn = 8 , lpStartByte = 158 , lpLength = 20 } + } + , stmt_annot = LP - { lpLine = 10 , lpColumn = 3 , lpStartByte = 162 , lpLength = 13 }) - LP - { lpLine = 10 , lpColumn = 3 , lpStartByte = 162 , lpLength = 14 } - ] - LP - { lpLine = 9 , lpColumn = 8 , lpStartByte = 158 , lpLength = 20 } - ) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 104 , lpLength = 74 }) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 104 , lpLength = 74 } - ] - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 178 } + { lpLine = 7 , lpColumn = 1 , lpStartByte = 104 , lpLength = 74 } + } + , toplevel_annot = + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 104 , lpLength = 74 } + } + ] + , program_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 178 } + } diff --git a/test/testcase/Batsh/function.ast b/test/testcase/Batsh/function.ast index 3a1ec48..0d57a32 100644 --- a/test/testcase/Batsh/function.ast +++ b/test/testcase/Batsh/function.ast @@ -1,508 +1,1028 @@ Program - [ Statement - (Comment - " Function call" - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 16 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 16 } - , Function - ( "func1" - , [ "p1" , "p2" ] - , [ Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "p1" - LP - { lpLine = 3 , lpColumn = 11 , lpStartByte = 52 , lpLength = 2 }) - LP { lpLine = 3 , lpColumn = 11 , lpStartByte = 52 , lpLength = 2 } - , LeftValue - (Identifier - "p2" - LP - { lpLine = 3 , lpColumn = 15 , lpStartByte = 56 , lpLength = 2 }) - LP { lpLine = 3 , lpColumn = 15 , lpStartByte = 56 , lpLength = 2 } - ] - ) - LP - { lpLine = 3 , lpColumn = 3 , lpStartByte = 44 , lpLength = 15 }) - LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 44 , lpLength = 16 } - ] - ) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 17 , lpLength = 45 } - , Statement - (Expression - (Call - ( "func1" - , [ Literal - (String - "Hello" - LP { lpLine = 5 , lpColumn = 7 , lpStartByte = 69 , lpLength = 7 }) - LP { lpLine = 5 , lpColumn = 7 , lpStartByte = 69 , lpLength = 7 } - , Literal - (String - "World" - LP - { lpLine = 5 , lpColumn = 16 , lpStartByte = 78 , lpLength = 7 }) - LP { lpLine = 5 , lpColumn = 16 , lpStartByte = 78 , lpLength = 7 } + { program_topls = + [ Statement + { toplevel_stmt = + Comment + { stmt_comment = " Function call" + , stmt_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 16 } + } + , toplevel_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 16 } + } + , Function + { toplevel_func = "func1" + , toplevel_params = [ "p1" , "p2" ] + , toplevel_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "p1" + , lvalue_annot = + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 52 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 52 + , lpLength = 2 + } + } + , LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "p2" + , lvalue_annot = + LP + { lpLine = 3 + , lpColumn = 15 + , lpStartByte = 56 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 3 + , lpColumn = 15 + , lpStartByte = 56 + , lpLength = 2 + } + } + ] + , expr_annot = + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 44 , lpLength = 15 } + } + , stmt_annot = + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 44 , lpLength = 16 } + } ] - ) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 63 , lpLength = 23 }) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 63 , lpLength = 24 }) - LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 63 , lpLength = 24 } - , Statement - (Comment - " Global and local variables" - LP - { lpLine = 6 , lpColumn = 1 , lpStartByte = 88 , lpLength = 29 }) - LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 88 , lpLength = 29 } - , Statement - (Expression - (Assign - ( Identifier - "v1" - LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 2 } - , Literal - (String - "Global V1" - LP - { lpLine = 7 , lpColumn = 6 , lpStartByte = 123 , lpLength = 11 }) - LP - { lpLine = 7 , lpColumn = 6 , lpStartByte = 123 , lpLength = 11 } - ) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 16 }) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 17 }) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 17 } - , Statement - (Expression - (Assign - ( Identifier - "v2" - LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 2 } - , Literal - (String - "Global V2" - LP - { lpLine = 8 , lpColumn = 6 , lpStartByte = 141 , lpLength = 11 }) - LP - { lpLine = 8 , lpColumn = 6 , lpStartByte = 141 , lpLength = 11 } - ) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 16 }) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 17 }) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 17 } - , Statement - (Expression - (Assign - ( Identifier - "v3" - LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 2 } - , Literal - (String - "Global V3" - LP - { lpLine = 9 , lpColumn = 6 , lpStartByte = 159 , lpLength = 11 }) - LP - { lpLine = 9 , lpColumn = 6 , lpStartByte = 159 , lpLength = 11 } - ) - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 16 }) - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 17 }) - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 17 } - , Function - ( "func2" - , [ "p" ] - , [ Expression - (Assign - ( Identifier - "v1" - LP - { lpLine = 11 , lpColumn = 3 , lpStartByte = 194 , lpLength = 2 } - , Binary - ( Concat - LP - { lpLine = 11 , lpColumn = 17 , lpStartByte = 208 , lpLength = 2 } - , Literal - (String - "Local " + , toplevel_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 17 , lpLength = 45 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "func1" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Hello" + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 7 + , lpStartByte = 69 + , lpLength = 7 + } + } + , expr_annot = + LP { lpLine = 5 , lpColumn = 7 , lpStartByte = 69 , lpLength = 7 } + } + , Literal + { expr_literal = + String + { literal_str = "World" + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 16 + , lpStartByte = 78 + , lpLength = 7 + } + } + , expr_annot = + LP + { lpLine = 5 , lpColumn = 16 , lpStartByte = 78 , lpLength = 7 } + } + ] + , expr_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 63 , lpLength = 23 } + } + , stmt_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 63 , lpLength = 24 } + } + , toplevel_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 63 , lpLength = 24 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " Global and local variables" + , stmt_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 88 , lpLength = 29 } + } + , toplevel_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 88 , lpLength = 29 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v1" + , lvalue_annot = + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 2 } + } + , expr_subExpr = + Literal + { expr_literal = + String + { literal_str = "Global V1" + , literal_annot = + LP + { lpLine = 7 + , lpColumn = 6 + , lpStartByte = 123 + , lpLength = 11 + } + } + , expr_annot = + LP + { lpLine = 7 , lpColumn = 6 , lpStartByte = 123 , lpLength = 11 } + } + , expr_annot = LP - { lpLine = 11 , lpColumn = 8 , lpStartByte = 199 , lpLength = 8 }) - LP - { lpLine = 11 , lpColumn = 8 , lpStartByte = 199 , lpLength = 8 } - , LeftValue - (Identifier - "p" + { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 16 } + } + , stmt_annot = + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 17 } + } + , toplevel_annot = + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v2" + , lvalue_annot = + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 2 } + } + , expr_subExpr = + Literal + { expr_literal = + String + { literal_str = "Global V2" + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 6 + , lpStartByte = 141 + , lpLength = 11 + } + } + , expr_annot = + LP + { lpLine = 8 , lpColumn = 6 , lpStartByte = 141 , lpLength = 11 } + } + , expr_annot = LP - { lpLine = 11 , lpColumn = 20 , lpStartByte = 211 , lpLength = 1 }) - LP - { lpLine = 11 , lpColumn = 20 , lpStartByte = 211 , lpLength = 1 } - ) - LP - { lpLine = 11 , lpColumn = 8 , lpStartByte = 199 , lpLength = 13 } - ) - LP - { lpLine = 11 , lpColumn = 3 , lpStartByte = 194 , lpLength = 18 }) - LP - { lpLine = 11 , lpColumn = 3 , lpStartByte = 194 , lpLength = 19 } - , Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "v1" - LP - { lpLine = 12 , lpColumn = 11 , lpStartByte = 224 , lpLength = 2 }) - LP - { lpLine = 12 , lpColumn = 11 , lpStartByte = 224 , lpLength = 2 } - ] - ) - LP - { lpLine = 12 , lpColumn = 3 , lpStartByte = 216 , lpLength = 11 }) - LP - { lpLine = 12 , lpColumn = 3 , lpStartByte = 216 , lpLength = 12 } - , Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "v2" - LP - { lpLine = 13 , lpColumn = 11 , lpStartByte = 239 , lpLength = 2 }) - LP - { lpLine = 13 , lpColumn = 11 , lpStartByte = 239 , lpLength = 2 } - ] - ) - LP - { lpLine = 13 , lpColumn = 3 , lpStartByte = 231 , lpLength = 11 }) - LP - { lpLine = 13 , lpColumn = 3 , lpStartByte = 231 , lpLength = 12 } - , Global - "v3" - LP - { lpLine = 14 , lpColumn = 3 , lpStartByte = 246 , lpLength = 10 } - , Global - "v4" - LP - { lpLine = 15 , lpColumn = 3 , lpStartByte = 259 , lpLength = 10 } - , Expression - (Assign - ( Identifier - "v3" - LP - { lpLine = 16 , lpColumn = 3 , lpStartByte = 272 , lpLength = 2 } - , Literal - (String - "V3 Modified." + { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 16 } + } + , stmt_annot = + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 17 } + } + , toplevel_annot = + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v3" + , lvalue_annot = + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 2 } + } + , expr_subExpr = + Literal + { expr_literal = + String + { literal_str = "Global V3" + , literal_annot = + LP + { lpLine = 9 + , lpColumn = 6 + , lpStartByte = 159 + , lpLength = 11 + } + } + , expr_annot = + LP + { lpLine = 9 , lpColumn = 6 , lpStartByte = 159 , lpLength = 11 } + } + , expr_annot = + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 16 } + } + , stmt_annot = + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 17 } + } + , toplevel_annot = + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 17 } + } + , Function + { toplevel_func = "func2" + , toplevel_params = [ "p" ] + , toplevel_stmts = + [ Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v1" + , lvalue_annot = + LP + { lpLine = 11 + , lpColumn = 3 + , lpStartByte = 194 + , lpLength = 2 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 11 + , lpColumn = 17 + , lpStartByte = 208 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "Local " + , literal_annot = + LP + { lpLine = 11 + , lpColumn = 8 + , lpStartByte = 199 + , lpLength = 8 + } + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 8 + , lpStartByte = 199 + , lpLength = 8 + } + } + , expr_right = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "p" + , lvalue_annot = + LP + { lpLine = 11 + , lpColumn = 20 + , lpStartByte = 211 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 20 + , lpStartByte = 211 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 8 + , lpStartByte = 199 + , lpLength = 13 + } + } + , expr_annot = + LP + { lpLine = 11 , lpColumn = 3 , lpStartByte = 194 , lpLength = 18 } + } + , stmt_annot = LP - { lpLine = 16 , lpColumn = 8 , lpStartByte = 277 , lpLength = 14 }) - LP - { lpLine = 16 , lpColumn = 8 , lpStartByte = 277 , lpLength = 14 } - ) - LP - { lpLine = 16 , lpColumn = 3 , lpStartByte = 272 , lpLength = 19 }) - LP - { lpLine = 16 , lpColumn = 3 , lpStartByte = 272 , lpLength = 20 } - ] - ) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 172 , lpLength = 122 } - , Statement - (Expression - (Call - ( "func2" - , [ Literal - (String - "Var" - LP - { lpLine = 18 , lpColumn = 7 , lpStartByte = 301 , lpLength = 5 }) - LP - { lpLine = 18 , lpColumn = 7 , lpStartByte = 301 , lpLength = 5 } - ] - ) - LP - { lpLine = 18 , lpColumn = 1 , lpStartByte = 295 , lpLength = 12 }) - LP - { lpLine = 18 , lpColumn = 1 , lpStartByte = 295 , lpLength = 13 }) - LP - { lpLine = 18 , lpColumn = 1 , lpStartByte = 295 , lpLength = 13 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "v1" - LP - { lpLine = 19 , lpColumn = 9 , lpStartByte = 317 , lpLength = 2 }) - LP - { lpLine = 19 , lpColumn = 9 , lpStartByte = 317 , lpLength = 2 } - ] - ) - LP - { lpLine = 19 , lpColumn = 1 , lpStartByte = 309 , lpLength = 11 }) - LP - { lpLine = 19 , lpColumn = 1 , lpStartByte = 309 , lpLength = 12 }) - LP - { lpLine = 19 , lpColumn = 1 , lpStartByte = 309 , lpLength = 12 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "v3" - LP - { lpLine = 20 , lpColumn = 9 , lpStartByte = 330 , lpLength = 2 }) - LP - { lpLine = 20 , lpColumn = 9 , lpStartByte = 330 , lpLength = 2 } - ] - ) - LP - { lpLine = 20 , lpColumn = 1 , lpStartByte = 322 , lpLength = 11 }) - LP - { lpLine = 20 , lpColumn = 1 , lpStartByte = 322 , lpLength = 12 }) - LP - { lpLine = 20 , lpColumn = 1 , lpStartByte = 322 , lpLength = 12 } - , Statement - (Comment - " Return value" - LP - { lpLine = 21 , lpColumn = 1 , lpStartByte = 335 , lpLength = 15 }) - LP - { lpLine = 21 , lpColumn = 1 , lpStartByte = 335 , lpLength = 15 } - , Function - ( "func3" - , [ "num" ] - , [ Return - (Just - (Binary - ( Plus + { lpLine = 11 , lpColumn = 3 , lpStartByte = 194 , lpLength = 19 } + } + , Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "v1" + , lvalue_annot = + LP + { lpLine = 12 + , lpColumn = 11 + , lpStartByte = 224 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 11 + , lpStartByte = 224 + , lpLength = 2 + } + } + ] + , expr_annot = + LP + { lpLine = 12 , lpColumn = 3 , lpStartByte = 216 , lpLength = 11 } + } + , stmt_annot = + LP + { lpLine = 12 , lpColumn = 3 , lpStartByte = 216 , lpLength = 12 } + } + , Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "v2" + , lvalue_annot = + LP + { lpLine = 13 + , lpColumn = 11 + , lpStartByte = 239 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 13 + , lpColumn = 11 + , lpStartByte = 239 + , lpLength = 2 + } + } + ] + , expr_annot = + LP + { lpLine = 13 , lpColumn = 3 , lpStartByte = 231 , lpLength = 11 } + } + , stmt_annot = LP - { lpLine = 23 , lpColumn = 14 , lpStartByte = 386 , lpLength = 1 } - , LeftValue - (Identifier - "num" - LP - { lpLine = 23 , lpColumn = 10 , lpStartByte = 382 , lpLength = 3 }) + { lpLine = 13 , lpColumn = 3 , lpStartByte = 231 , lpLength = 12 } + } + , Global + { stmt_ident = "v3" + , stmt_annot = LP - { lpLine = 23 , lpColumn = 10 , lpStartByte = 382 , lpLength = 3 } - , Literal - (Int - 41 - LP - { lpLine = 23 , lpColumn = 16 , lpStartByte = 388 , lpLength = 2 }) + { lpLine = 14 , lpColumn = 3 , lpStartByte = 246 , lpLength = 10 } + } + , Global + { stmt_ident = "v4" + , stmt_annot = LP - { lpLine = 23 , lpColumn = 16 , lpStartByte = 388 , lpLength = 2 } - ) - LP - { lpLine = 23 - , lpColumn = 10 - , lpStartByte = 382 - , lpLength = 8 - })) - LP - { lpLine = 23 , lpColumn = 3 , lpStartByte = 375 , lpLength = 16 } - ] - ) - LP - { lpLine = 22 , lpColumn = 1 , lpStartByte = 351 , lpLength = 42 } - , Statement - (Expression - (Call - ( "func3" - , [ Literal - (Int - 4 - LP - { lpLine = 25 , lpColumn = 7 , lpStartByte = 400 , lpLength = 1 }) - LP - { lpLine = 25 , lpColumn = 7 , lpStartByte = 400 , lpLength = 1 } + { lpLine = 15 , lpColumn = 3 , lpStartByte = 259 , lpLength = 10 } + } + , Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v3" + , lvalue_annot = + LP + { lpLine = 16 + , lpColumn = 3 + , lpStartByte = 272 + , lpLength = 2 + } + } + , expr_subExpr = + Literal + { expr_literal = + String + { literal_str = "V3 Modified." + , literal_annot = + LP + { lpLine = 16 + , lpColumn = 8 + , lpStartByte = 277 + , lpLength = 14 + } + } + , expr_annot = + LP + { lpLine = 16 + , lpColumn = 8 + , lpStartByte = 277 + , lpLength = 14 + } + } + , expr_annot = + LP + { lpLine = 16 , lpColumn = 3 , lpStartByte = 272 , lpLength = 19 } + } + , stmt_annot = + LP + { lpLine = 16 , lpColumn = 3 , lpStartByte = 272 , lpLength = 20 } + } ] - ) - LP - { lpLine = 25 , lpColumn = 1 , lpStartByte = 394 , lpLength = 8 }) - LP - { lpLine = 25 , lpColumn = 1 , lpStartByte = 394 , lpLength = 9 }) - LP - { lpLine = 25 , lpColumn = 1 , lpStartByte = 394 , lpLength = 9 } - , Statement - (Expression - (Call - ( "println" , [] ) - LP - { lpLine = 26 , lpColumn = 1 , lpStartByte = 404 , lpLength = 9 }) - LP - { lpLine = 26 , lpColumn = 1 , lpStartByte = 404 , lpLength = 10 }) - LP - { lpLine = 26 , lpColumn = 1 , lpStartByte = 404 , lpLength = 10 } - , Statement - (Expression - (Assign - ( Identifier - "ret" - LP - { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 3 } - , Call - ( "func3" - , [ Literal - (Int - 1 - LP - { lpLine = 27 , lpColumn = 13 , lpStartByte = 427 , lpLength = 1 }) + , toplevel_annot = + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 172 , lpLength = 122 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "func2" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Var" + , literal_annot = + LP + { lpLine = 18 + , lpColumn = 7 + , lpStartByte = 301 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 18 + , lpColumn = 7 + , lpStartByte = 301 + , lpLength = 5 + } + } + ] + , expr_annot = + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 295 , lpLength = 12 } + } + , stmt_annot = + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 295 , lpLength = 13 } + } + , toplevel_annot = + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 295 , lpLength = 13 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "v1" + , lvalue_annot = + LP + { lpLine = 19 + , lpColumn = 9 + , lpStartByte = 317 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 19 + , lpColumn = 9 + , lpStartByte = 317 + , lpLength = 2 + } + } + ] + , expr_annot = + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 309 , lpLength = 11 } + } + , stmt_annot = + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 309 , lpLength = 12 } + } + , toplevel_annot = + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 309 , lpLength = 12 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "v3" + , lvalue_annot = + LP + { lpLine = 20 + , lpColumn = 9 + , lpStartByte = 330 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 20 + , lpColumn = 9 + , lpStartByte = 330 + , lpLength = 2 + } + } + ] + , expr_annot = + LP + { lpLine = 20 , lpColumn = 1 , lpStartByte = 322 , lpLength = 11 } + } + , stmt_annot = + LP + { lpLine = 20 , lpColumn = 1 , lpStartByte = 322 , lpLength = 12 } + } + , toplevel_annot = + LP + { lpLine = 20 , lpColumn = 1 , lpStartByte = 322 , lpLength = 12 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " Return value" + , stmt_annot = + LP + { lpLine = 21 , lpColumn = 1 , lpStartByte = 335 , lpLength = 15 } + } + , toplevel_annot = + LP + { lpLine = 21 , lpColumn = 1 , lpStartByte = 335 , lpLength = 15 } + } + , Function + { toplevel_func = "func3" + , toplevel_params = [ "num" ] + , toplevel_stmts = + [ Return + { stmt_retval = + Just + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 23 + , lpColumn = 14 + , lpStartByte = 386 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 23 + , lpColumn = 10 + , lpStartByte = 382 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 23 + , lpColumn = 10 + , lpStartByte = 382 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 41 + , literal_annot = + LP + { lpLine = 23 + , lpColumn = 16 + , lpStartByte = 388 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 23 + , lpColumn = 16 + , lpStartByte = 388 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 23 , lpColumn = 10 , lpStartByte = 382 , lpLength = 8 } + } + , stmt_annot = LP - { lpLine = 27 , lpColumn = 13 , lpStartByte = 427 , lpLength = 1 } - ] - ) - LP - { lpLine = 27 , lpColumn = 7 , lpStartByte = 421 , lpLength = 8 } - ) - LP - { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 14 }) - LP - { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 15 }) - LP - { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 15 } - , Statement - (Expression - (Call - ( "println" - , [ Literal - (String - "Returned:" - LP - { lpLine = 28 , lpColumn = 9 , lpStartByte = 439 , lpLength = 11 }) - LP - { lpLine = 28 , lpColumn = 9 , lpStartByte = 439 , lpLength = 11 } - , LeftValue - (Identifier - "ret" - LP - { lpLine = 28 , lpColumn = 22 , lpStartByte = 452 , lpLength = 3 }) - LP - { lpLine = 28 , lpColumn = 22 , lpStartByte = 452 , lpLength = 3 } + { lpLine = 23 , lpColumn = 3 , lpStartByte = 375 , lpLength = 16 } + } ] - ) - LP - { lpLine = 28 , lpColumn = 1 , lpStartByte = 431 , lpLength = 25 }) - LP - { lpLine = 28 , lpColumn = 1 , lpStartByte = 431 , lpLength = 26 }) - LP - { lpLine = 28 , lpColumn = 1 , lpStartByte = 431 , lpLength = 26 } - , Statement - (Comment - " Argument containing space" - LP - { lpLine = 29 , lpColumn = 1 , lpStartByte = 458 , lpLength = 28 }) - LP - { lpLine = 29 , lpColumn = 1 , lpStartByte = 458 , lpLength = 28 } - , Function - ( "g" - , [ "text" ] - , [ Return - (Just - (LeftValue - (Identifier - "text" - LP - { lpLine = 31 , lpColumn = 10 , lpStartByte = 515 , lpLength = 4 }) - LP - { lpLine = 31 - , lpColumn = 10 - , lpStartByte = 515 - , lpLength = 4 - })) - LP - { lpLine = 31 , lpColumn = 3 , lpStartByte = 508 , lpLength = 12 } - ] - ) - LP - { lpLine = 30 , lpColumn = 1 , lpStartByte = 487 , lpLength = 35 } - , Function - ( "f" - , [ "text" ] - , [ Return - (Just - (Call - ( "g" - , [ LeftValue - (Identifier - "text" - LP - { lpLine = 34 , lpColumn = 12 , lpStartByte = 553 , lpLength = 4 }) - LP - { lpLine = 34 , lpColumn = 12 , lpStartByte = 553 , lpLength = 4 } - ] - ) - LP - { lpLine = 34 - , lpColumn = 10 - , lpStartByte = 551 - , lpLength = 7 - })) - LP - { lpLine = 34 , lpColumn = 3 , lpStartByte = 544 , lpLength = 15 } - ] - ) - LP - { lpLine = 33 , lpColumn = 1 , lpStartByte = 523 , lpLength = 38 } - , Statement - (Expression - (Assign - ( Identifier - "test" - LP - { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 4 } - , Call - ( "f" - , [ Literal - (String - "Param with space" - LP - { lpLine = 36 - , lpColumn = 10 - , lpStartByte = 571 - , lpLength = 18 - }) + , toplevel_annot = + LP + { lpLine = 22 , lpColumn = 1 , lpStartByte = 351 , lpLength = 42 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "func3" + , expr_params = + [ Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + LP + { lpLine = 25 + , lpColumn = 7 + , lpStartByte = 400 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 25 + , lpColumn = 7 + , lpStartByte = 400 + , lpLength = 1 + } + } + ] + , expr_annot = + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 394 , lpLength = 8 } + } + , stmt_annot = + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 394 , lpLength = 9 } + } + , toplevel_annot = + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 394 , lpLength = 9 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = [] + , expr_annot = + LP + { lpLine = 26 , lpColumn = 1 , lpStartByte = 404 , lpLength = 9 } + } + , stmt_annot = + LP + { lpLine = 26 , lpColumn = 1 , lpStartByte = 404 , lpLength = 10 } + } + , toplevel_annot = + LP + { lpLine = 26 , lpColumn = 1 , lpStartByte = 404 , lpLength = 10 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "ret" + , lvalue_annot = + LP + { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 3 } + } + , expr_subExpr = + Call + { expr_func = "func3" + , expr_params = + [ Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 27 + , lpColumn = 13 + , lpStartByte = 427 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 27 + , lpColumn = 13 + , lpStartByte = 427 + , lpLength = 1 + } + } + ] + , expr_annot = + LP + { lpLine = 27 , lpColumn = 7 , lpStartByte = 421 , lpLength = 8 } + } + , expr_annot = + LP + { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 14 } + } + , stmt_annot = + LP + { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 15 } + } + , toplevel_annot = + LP + { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Returned:" + , literal_annot = + LP + { lpLine = 28 + , lpColumn = 9 + , lpStartByte = 439 + , lpLength = 11 + } + } + , expr_annot = + LP + { lpLine = 28 + , lpColumn = 9 + , lpStartByte = 439 + , lpLength = 11 + } + } + , LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "ret" + , lvalue_annot = + LP + { lpLine = 28 + , lpColumn = 22 + , lpStartByte = 452 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 28 + , lpColumn = 22 + , lpStartByte = 452 + , lpLength = 3 + } + } + ] + , expr_annot = + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 431 , lpLength = 25 } + } + , stmt_annot = + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 431 , lpLength = 26 } + } + , toplevel_annot = + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 431 , lpLength = 26 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " Argument containing space" + , stmt_annot = + LP + { lpLine = 29 , lpColumn = 1 , lpStartByte = 458 , lpLength = 28 } + } + , toplevel_annot = + LP + { lpLine = 29 , lpColumn = 1 , lpStartByte = 458 , lpLength = 28 } + } + , Function + { toplevel_func = "g" + , toplevel_params = [ "text" ] + , toplevel_stmts = + [ Return + { stmt_retval = + Just + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "text" + , lvalue_annot = + LP + { lpLine = 31 + , lpColumn = 10 + , lpStartByte = 515 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 31 , lpColumn = 10 , lpStartByte = 515 , lpLength = 4 } + } + , stmt_annot = LP - { lpLine = 36 , lpColumn = 10 , lpStartByte = 571 , lpLength = 18 } - ] - ) - LP - { lpLine = 36 , lpColumn = 8 , lpStartByte = 569 , lpLength = 21 } - ) - LP - { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 28 }) - LP - { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 29 }) - LP - { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 29 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "test" - LP - { lpLine = 37 , lpColumn = 9 , lpStartByte = 600 , lpLength = 4 }) - LP - { lpLine = 37 , lpColumn = 9 , lpStartByte = 600 , lpLength = 4 } + { lpLine = 31 , lpColumn = 3 , lpStartByte = 508 , lpLength = 12 } + } ] - ) - LP - { lpLine = 37 , lpColumn = 1 , lpStartByte = 592 , lpLength = 13 }) - LP - { lpLine = 37 , lpColumn = 1 , lpStartByte = 592 , lpLength = 14 }) - LP - { lpLine = 37 , lpColumn = 1 , lpStartByte = 592 , lpLength = 14 } - ] - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 606 } + , toplevel_annot = + LP + { lpLine = 30 , lpColumn = 1 , lpStartByte = 487 , lpLength = 35 } + } + , Function + { toplevel_func = "f" + , toplevel_params = [ "text" ] + , toplevel_stmts = + [ Return + { stmt_retval = + Just + Call + { expr_func = "g" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "text" + , lvalue_annot = + LP + { lpLine = 34 + , lpColumn = 12 + , lpStartByte = 553 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 34 + , lpColumn = 12 + , lpStartByte = 553 + , lpLength = 4 + } + } + ] + , expr_annot = + LP + { lpLine = 34 , lpColumn = 10 , lpStartByte = 551 , lpLength = 7 } + } + , stmt_annot = + LP + { lpLine = 34 , lpColumn = 3 , lpStartByte = 544 , lpLength = 15 } + } + ] + , toplevel_annot = + LP + { lpLine = 33 , lpColumn = 1 , lpStartByte = 523 , lpLength = 38 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "test" + , lvalue_annot = + LP + { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 4 } + } + , expr_subExpr = + Call + { expr_func = "f" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Param with space" + , literal_annot = + LP + { lpLine = 36 + , lpColumn = 10 + , lpStartByte = 571 + , lpLength = 18 + } + } + , expr_annot = + LP + { lpLine = 36 + , lpColumn = 10 + , lpStartByte = 571 + , lpLength = 18 + } + } + ] + , expr_annot = + LP + { lpLine = 36 , lpColumn = 8 , lpStartByte = 569 , lpLength = 21 } + } + , expr_annot = + LP + { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 28 } + } + , stmt_annot = + LP + { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 29 } + } + , toplevel_annot = + LP + { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 29 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "test" + , lvalue_annot = + LP + { lpLine = 37 + , lpColumn = 9 + , lpStartByte = 600 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 37 + , lpColumn = 9 + , lpStartByte = 600 + , lpLength = 4 + } + } + ] + , expr_annot = + LP + { lpLine = 37 , lpColumn = 1 , lpStartByte = 592 , lpLength = 13 } + } + , stmt_annot = + LP + { lpLine = 37 , lpColumn = 1 , lpStartByte = 592 , lpLength = 14 } + } + , toplevel_annot = + LP + { lpLine = 37 , lpColumn = 1 , lpStartByte = 592 , lpLength = 14 } + } + ] + , program_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 606 } + } diff --git a/test/testcase/Batsh/if.ast b/test/testcase/Batsh/if.ast index 52a5a23..c764c7a 100644 --- a/test/testcase/Batsh/if.ast +++ b/test/testcase/Batsh/if.ast @@ -1,490 +1,1061 @@ Program - [ Statement - (If - ( Binary - ( Less - LP { lpLine = 1 , lpColumn = 7 , lpStartByte = 6 , lpLength = 1 } - , Literal - (Int - 2 - LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 }) - LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } - , Literal - (Int - 10 - LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 2 }) - LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 2 } - ) - LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 6 } - , Block - [ Expression - (Call - ( "println" - , [ Literal - (String - "Yes" - LP - { lpLine = 2 , lpColumn = 11 , lpStartByte = 24 , lpLength = 5 }) - LP { lpLine = 2 , lpColumn = 11 , lpStartByte = 24 , lpLength = 5 } - ] - ) - LP - { lpLine = 2 , lpColumn = 3 , lpStartByte = 16 , lpLength = 14 }) - LP { lpLine = 2 , lpColumn = 3 , lpStartByte = 16 , lpLength = 15 } - ] - LP - { lpLine = 1 , lpColumn = 13 , lpStartByte = 12 , lpLength = 21 } - ) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } - , Statement - (IfElse - ( Literal - (Bool - True - LP { lpLine = 4 , lpColumn = 5 , lpStartByte = 38 , lpLength = 4 }) - LP { lpLine = 4 , lpColumn = 5 , lpStartByte = 38 , lpLength = 4 } - , Block - [ IfElse - ( Literal - (Bool - False - LP { lpLine = 5 , lpColumn = 7 , lpStartByte = 52 , lpLength = 5 }) - LP { lpLine = 5 , lpColumn = 7 , lpStartByte = 52 , lpLength = 5 } - , Block - [ Expression - (Assign - ( Identifier - "v" - LP { lpLine = 6 , lpColumn = 5 , lpStartByte = 65 , lpLength = 1 } - , Binary - ( Plus - LP - { lpLine = 6 - , lpColumn = 11 - , lpStartByte = 71 - , lpLength = 1 - } - , Literal - (Int - 4 - LP - { lpLine = 6 - , lpColumn = 9 - , lpStartByte = 69 - , lpLength = 1 - }) - LP - { lpLine = 6 - , lpColumn = 9 - , lpStartByte = 69 - , lpLength = 1 - } - , Literal - (Int - 1 - LP - { lpLine = 6 - , lpColumn = 13 - , lpStartByte = 73 - , lpLength = 1 - }) - LP - { lpLine = 6 - , lpColumn = 13 - , lpStartByte = 73 - , lpLength = 1 - } - ) - LP { lpLine = 6 , lpColumn = 9 , lpStartByte = 69 , lpLength = 5 } - ) - LP { lpLine = 6 , lpColumn = 5 , lpStartByte = 65 , lpLength = 9 }) - LP { lpLine = 6 , lpColumn = 5 , lpStartByte = 65 , lpLength = 10 } - ] - LP - { lpLine = 5 , lpColumn = 14 , lpStartByte = 59 , lpLength = 20 } - , Block - [ Expression - (Assign - ( Identifier - "v" - LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 91 , lpLength = 1 } - , Literal - (Int - 2 - LP - { lpLine = 8 - , lpColumn = 9 - , lpStartByte = 95 - , lpLength = 1 - }) - LP { lpLine = 8 , lpColumn = 9 , lpStartByte = 95 , lpLength = 1 } - ) - LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 91 , lpLength = 5 }) - LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 91 , lpLength = 6 } - ] - LP - { lpLine = 7 , lpColumn = 10 , lpStartByte = 85 , lpLength = 16 } - ) - LP { lpLine = 5 , lpColumn = 3 , lpStartByte = 48 , lpLength = 53 } - , If - ( Literal - (Bool - False - LP - { lpLine = 10 , lpColumn = 7 , lpStartByte = 108 , lpLength = 5 }) - LP - { lpLine = 10 , lpColumn = 7 , lpStartByte = 108 , lpLength = 5 } - , Expression - (Call - ( "println" - , [ Literal - (String - "no" - LP - { lpLine = 10 - , lpColumn = 22 - , lpStartByte = 123 - , lpLength = 4 - }) - LP - { lpLine = 10 , lpColumn = 22 , lpStartByte = 123 , lpLength = 4 } + { program_topls = + [ Statement + { toplevel_stmt = + If + { stmt_expr = + Binary + { expr_binOp = + Less + { binOp_annot = + LP { lpLine = 1 , lpColumn = 7 , lpStartByte = 6 , lpLength = 1 } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 5 + , lpStartByte = 4 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 10 + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 9 + , lpStartByte = 8 + , lpLength = 2 + } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 2 } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 6 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Yes" + , literal_annot = + LP + { lpLine = 2 + , lpColumn = 11 + , lpStartByte = 24 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 2 + , lpColumn = 11 + , lpStartByte = 24 + , lpLength = 5 + } + } + ] + , expr_annot = + LP + { lpLine = 2 + , lpColumn = 3 + , lpStartByte = 16 + , lpLength = 14 + } + } + , stmt_annot = + LP + { lpLine = 2 , lpColumn = 3 , lpStartByte = 16 , lpLength = 15 } + } ] - ) - LP - { lpLine = 10 - , lpColumn = 14 - , lpStartByte = 115 - , lpLength = 13 - }) - LP - { lpLine = 10 , lpColumn = 14 , lpStartByte = 115 , lpLength = 14 } - ) - LP - { lpLine = 10 , lpColumn = 3 , lpStartByte = 104 , lpLength = 25 } - ] - LP - { lpLine = 4 , lpColumn = 11 , lpStartByte = 44 , lpLength = 87 } - , Block - [] - LP - { lpLine = 11 , lpColumn = 8 , lpStartByte = 137 , lpLength = 4 } - ) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 34 , lpLength = 107 }) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 34 , lpLength = 107 } - , Statement - (Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "v" - LP - { lpLine = 14 , lpColumn = 9 , lpStartByte = 150 , lpLength = 1 }) - LP - { lpLine = 14 , lpColumn = 9 , lpStartByte = 150 , lpLength = 1 } - ] - ) - LP - { lpLine = 14 , lpColumn = 1 , lpStartByte = 142 , lpLength = 10 }) - LP - { lpLine = 14 , lpColumn = 1 , lpStartByte = 142 , lpLength = 11 }) - LP - { lpLine = 14 , lpColumn = 1 , lpStartByte = 142 , lpLength = 11 } - , Statement - (If - ( Binary - ( Greater - LP - { lpLine = 15 , lpColumn = 7 , lpStartByte = 160 , lpLength = 1 } - , Literal - (Int - 2 - LP - { lpLine = 15 , lpColumn = 5 , lpStartByte = 158 , lpLength = 1 }) - LP - { lpLine = 15 , lpColumn = 5 , lpStartByte = 158 , lpLength = 1 } - , Literal - (Int - 1 - LP - { lpLine = 15 , lpColumn = 9 , lpStartByte = 162 , lpLength = 1 }) - LP - { lpLine = 15 , lpColumn = 9 , lpStartByte = 162 , lpLength = 1 } - ) - LP - { lpLine = 15 , lpColumn = 5 , lpStartByte = 158 , lpLength = 5 } - , Expression - (Call - ( "println" - , [ Literal - (String - "True" - LP - { lpLine = 15 , lpColumn = 20 , lpStartByte = 173 , lpLength = 6 }) - LP - { lpLine = 15 , lpColumn = 20 , lpStartByte = 173 , lpLength = 6 } - ] - ) - LP - { lpLine = 15 - , lpColumn = 12 - , lpStartByte = 165 - , lpLength = 15 - }) - LP - { lpLine = 15 , lpColumn = 12 , lpStartByte = 165 , lpLength = 16 } - ) - LP - { lpLine = 15 , lpColumn = 1 , lpStartByte = 154 , lpLength = 27 }) - LP - { lpLine = 15 , lpColumn = 1 , lpStartByte = 154 , lpLength = 27 } - , Statement - (If - ( Binary - ( ArithEqual - LP - { lpLine = 16 , lpColumn = 7 , lpStartByte = 188 , lpLength = 3 } - , Literal - (Int - 1 - LP - { lpLine = 16 , lpColumn = 5 , lpStartByte = 186 , lpLength = 1 }) - LP - { lpLine = 16 , lpColumn = 5 , lpStartByte = 186 , lpLength = 1 } - , Literal - (Int - 12 - LP - { lpLine = 16 , lpColumn = 11 , lpStartByte = 192 , lpLength = 2 }) - LP - { lpLine = 16 , lpColumn = 11 , lpStartByte = 192 , lpLength = 2 } - ) - LP - { lpLine = 16 , lpColumn = 5 , lpStartByte = 186 , lpLength = 8 } - , Block - [ Expression - (Call - ( "println" - , [ Literal - (String - "No" - LP - { lpLine = 17 , lpColumn = 11 , lpStartByte = 208 , lpLength = 4 }) + , stmt_annot = LP - { lpLine = 17 , lpColumn = 11 , lpStartByte = 208 , lpLength = 4 } - ] - ) - LP - { lpLine = 17 , lpColumn = 3 , lpStartByte = 200 , lpLength = 13 }) - LP - { lpLine = 17 , lpColumn = 3 , lpStartByte = 200 , lpLength = 14 } - ] - LP - { lpLine = 16 , lpColumn = 15 , lpStartByte = 196 , lpLength = 20 } - ) - LP - { lpLine = 16 , lpColumn = 1 , lpStartByte = 182 , lpLength = 34 }) - LP - { lpLine = 16 , lpColumn = 1 , lpStartByte = 182 , lpLength = 34 } - , Statement - (IfElse - ( Binary - ( Equal - LP - { lpLine = 19 , lpColumn = 9 , lpStartByte = 225 , lpLength = 2 } - , Literal - (String - "a" - LP - { lpLine = 19 , lpColumn = 5 , lpStartByte = 221 , lpLength = 3 }) - LP - { lpLine = 19 , lpColumn = 5 , lpStartByte = 221 , lpLength = 3 } - , Literal - (String - "b" - LP - { lpLine = 19 , lpColumn = 12 , lpStartByte = 228 , lpLength = 3 }) - LP - { lpLine = 19 , lpColumn = 12 , lpStartByte = 228 , lpLength = 3 } - ) - LP - { lpLine = 19 , lpColumn = 5 , lpStartByte = 221 , lpLength = 10 } - , Block - [ Expression - (Call - ( "println" - , [ Literal - (String - "No" - LP - { lpLine = 20 , lpColumn = 11 , lpStartByte = 245 , lpLength = 4 }) + { lpLine = 1 , lpColumn = 13 , lpStartByte = 12 , lpLength = 21 } + } + , stmt_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } + } + , toplevel_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } + } + , Statement + { toplevel_stmt = + IfElse + { stmt_expr = + Literal + { expr_literal = + Bool + { literal_bool = True + , literal_annot = + LP { lpLine = 4 , lpColumn = 5 , lpStartByte = 38 , lpLength = 4 } + } + , expr_annot = + LP { lpLine = 4 , lpColumn = 5 , lpStartByte = 38 , lpLength = 4 } + } + , stmt_then = + Block + { stmt_stmts = + [ IfElse + { stmt_expr = + Literal + { expr_literal = + Bool + { literal_bool = False + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 7 + , lpStartByte = 52 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 7 + , lpStartByte = 52 + , lpLength = 5 + } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v" + , lvalue_annot = + LP + { lpLine = 6 + , lpColumn = 5 + , lpStartByte = 65 + , lpLength = 1 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 6 + , lpColumn = 11 + , lpStartByte = 71 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 69 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 69 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 6 + , lpColumn = 13 + , lpStartByte = 73 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 6 + , lpColumn = 13 + , lpStartByte = 73 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 69 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 6 + , lpColumn = 5 + , lpStartByte = 65 + , lpLength = 9 + } + } + , stmt_annot = + LP + { lpLine = 6 + , lpColumn = 5 + , lpStartByte = 65 + , lpLength = 10 + } + } + ] + , stmt_annot = + LP + { lpLine = 5 + , lpColumn = 14 + , lpStartByte = 59 + , lpLength = 20 + } + } + , stmt_else = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v" + , lvalue_annot = + LP + { lpLine = 8 + , lpColumn = 5 + , lpStartByte = 91 + , lpLength = 1 + } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 95 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 95 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 5 + , lpStartByte = 91 + , lpLength = 5 + } + } + , stmt_annot = + LP + { lpLine = 8 + , lpColumn = 5 + , lpStartByte = 91 + , lpLength = 6 + } + } + ] + , stmt_annot = + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 85 + , lpLength = 16 + } + } + , stmt_annot = + LP + { lpLine = 5 , lpColumn = 3 , lpStartByte = 48 , lpLength = 53 } + } + , If + { stmt_expr = + Literal + { expr_literal = + Bool + { literal_bool = False + , literal_annot = + LP + { lpLine = 10 + , lpColumn = 7 + , lpStartByte = 108 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 7 + , lpStartByte = 108 + , lpLength = 5 + } + } + , stmt_then = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "no" + , literal_annot = + LP + { lpLine = 10 + , lpColumn = 22 + , lpStartByte = 123 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 22 + , lpStartByte = 123 + , lpLength = 4 + } + } + ] + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 14 + , lpStartByte = 115 + , lpLength = 13 + } + } + , stmt_annot = + LP + { lpLine = 10 + , lpColumn = 14 + , lpStartByte = 115 + , lpLength = 14 + } + } + , stmt_annot = + LP + { lpLine = 10 + , lpColumn = 3 + , lpStartByte = 104 + , lpLength = 25 + } + } + ] + , stmt_annot = + LP + { lpLine = 4 , lpColumn = 11 , lpStartByte = 44 , lpLength = 87 } + } + , stmt_else = + Block + { stmt_stmts = [] + , stmt_annot = LP - { lpLine = 20 , lpColumn = 11 , lpStartByte = 245 , lpLength = 4 } - ] - ) + { lpLine = 11 , lpColumn = 8 , lpStartByte = 137 , lpLength = 4 } + } + , stmt_annot = LP - { lpLine = 20 , lpColumn = 3 , lpStartByte = 237 , lpLength = 13 }) - LP - { lpLine = 20 , lpColumn = 3 , lpStartByte = 237 , lpLength = 14 } - ] - LP - { lpLine = 19 , lpColumn = 17 , lpStartByte = 233 , lpLength = 20 } - , Block - [ Expression - (Call - ( "println" - , [ Literal - (String - "a is not b" - LP - { lpLine = 22 - , lpColumn = 11 - , lpStartByte = 271 - , lpLength = 12 - }) + { lpLine = 4 , lpColumn = 1 , lpStartByte = 34 , lpLength = 107 } + } + , toplevel_annot = + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 34 , lpLength = 107 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "v" + , lvalue_annot = + LP + { lpLine = 14 + , lpColumn = 9 + , lpStartByte = 150 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 14 + , lpColumn = 9 + , lpStartByte = 150 + , lpLength = 1 + } + } + ] + , expr_annot = LP - { lpLine = 22 , lpColumn = 11 , lpStartByte = 271 , lpLength = 12 } - ] - ) + { lpLine = 14 , lpColumn = 1 , lpStartByte = 142 , lpLength = 10 } + } + , stmt_annot = LP - { lpLine = 22 , lpColumn = 3 , lpStartByte = 263 , lpLength = 21 }) - LP - { lpLine = 22 , lpColumn = 3 , lpStartByte = 263 , lpLength = 22 } - ] - LP - { lpLine = 21 , lpColumn = 8 , lpStartByte = 259 , lpLength = 28 } - ) - LP - { lpLine = 19 , lpColumn = 1 , lpStartByte = 217 , lpLength = 70 }) - LP - { lpLine = 19 , lpColumn = 1 , lpStartByte = 217 , lpLength = 70 } - , Statement - (Expression - (Assign - ( Identifier - "num" - LP - { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 3 } - , Literal - (Int - 43 - LP - { lpLine = 24 , lpColumn = 7 , lpStartByte = 294 , lpLength = 2 }) - LP - { lpLine = 24 , lpColumn = 7 , lpStartByte = 294 , lpLength = 2 } - ) - LP - { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 8 }) - LP - { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 9 }) - LP - { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 9 } - , Statement - (If - ( Binary - ( Equal - LP - { lpLine = 25 , lpColumn = 10 , lpStartByte = 307 , lpLength = 2 } - , Literal - (String - "43" + { lpLine = 14 , lpColumn = 1 , lpStartByte = 142 , lpLength = 11 } + } + , toplevel_annot = + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 142 , lpLength = 11 } + } + , Statement + { toplevel_stmt = + If + { stmt_expr = + Binary + { expr_binOp = + Greater + { binOp_annot = + LP + { lpLine = 15 , lpColumn = 7 , lpStartByte = 160 , lpLength = 1 } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 15 + , lpColumn = 5 + , lpStartByte = 158 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 15 , lpColumn = 5 , lpStartByte = 158 , lpLength = 1 } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 15 + , lpColumn = 9 + , lpStartByte = 162 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 15 , lpColumn = 9 , lpStartByte = 162 , lpLength = 1 } + } + , expr_annot = + LP + { lpLine = 15 , lpColumn = 5 , lpStartByte = 158 , lpLength = 5 } + } + , stmt_then = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "True" + , literal_annot = + LP + { lpLine = 15 + , lpColumn = 20 + , lpStartByte = 173 + , lpLength = 6 + } + } + , expr_annot = + LP + { lpLine = 15 + , lpColumn = 20 + , lpStartByte = 173 + , lpLength = 6 + } + } + ] + , expr_annot = + LP + { lpLine = 15 + , lpColumn = 12 + , lpStartByte = 165 + , lpLength = 15 + } + } + , stmt_annot = + LP + { lpLine = 15 , lpColumn = 12 , lpStartByte = 165 , lpLength = 16 } + } + , stmt_annot = LP - { lpLine = 25 , lpColumn = 5 , lpStartByte = 302 , lpLength = 4 }) - LP - { lpLine = 25 , lpColumn = 5 , lpStartByte = 302 , lpLength = 4 } - , LeftValue - (Identifier - "num" + { lpLine = 15 , lpColumn = 1 , lpStartByte = 154 , lpLength = 27 } + } + , toplevel_annot = + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 154 , lpLength = 27 } + } + , Statement + { toplevel_stmt = + If + { stmt_expr = + Binary + { expr_binOp = + ArithEqual + { binOp_annot = + LP + { lpLine = 16 , lpColumn = 7 , lpStartByte = 188 , lpLength = 3 } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 16 + , lpColumn = 5 + , lpStartByte = 186 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 16 , lpColumn = 5 , lpStartByte = 186 , lpLength = 1 } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 12 + , literal_annot = + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 192 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 16 , lpColumn = 11 , lpStartByte = 192 , lpLength = 2 } + } + , expr_annot = + LP + { lpLine = 16 , lpColumn = 5 , lpStartByte = 186 , lpLength = 8 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "No" + , literal_annot = + LP + { lpLine = 17 + , lpColumn = 11 + , lpStartByte = 208 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 17 + , lpColumn = 11 + , lpStartByte = 208 + , lpLength = 4 + } + } + ] + , expr_annot = + LP + { lpLine = 17 + , lpColumn = 3 + , lpStartByte = 200 + , lpLength = 13 + } + } + , stmt_annot = + LP + { lpLine = 17 + , lpColumn = 3 + , lpStartByte = 200 + , lpLength = 14 + } + } + ] + , stmt_annot = + LP + { lpLine = 16 , lpColumn = 15 , lpStartByte = 196 , lpLength = 20 } + } + , stmt_annot = LP - { lpLine = 25 , lpColumn = 13 , lpStartByte = 310 , lpLength = 3 }) - LP - { lpLine = 25 , lpColumn = 13 , lpStartByte = 310 , lpLength = 3 } - ) - LP - { lpLine = 25 , lpColumn = 5 , lpStartByte = 302 , lpLength = 11 } - , Block - [ Expression - (Call - ( "println" - , [ Literal - (String - "43 == num" - LP - { lpLine = 26 - , lpColumn = 11 - , lpStartByte = 327 - , lpLength = 11 - }) + { lpLine = 16 , lpColumn = 1 , lpStartByte = 182 , lpLength = 34 } + } + , toplevel_annot = + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 182 , lpLength = 34 } + } + , Statement + { toplevel_stmt = + IfElse + { stmt_expr = + Binary + { expr_binOp = + Equal + { binOp_annot = + LP + { lpLine = 19 , lpColumn = 9 , lpStartByte = 225 , lpLength = 2 } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "a" + , literal_annot = + LP + { lpLine = 19 + , lpColumn = 5 + , lpStartByte = 221 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 19 , lpColumn = 5 , lpStartByte = 221 , lpLength = 3 } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "b" + , literal_annot = + LP + { lpLine = 19 + , lpColumn = 12 + , lpStartByte = 228 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 19 , lpColumn = 12 , lpStartByte = 228 , lpLength = 3 } + } + , expr_annot = + LP + { lpLine = 19 , lpColumn = 5 , lpStartByte = 221 , lpLength = 10 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "No" + , literal_annot = + LP + { lpLine = 20 + , lpColumn = 11 + , lpStartByte = 245 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 20 + , lpColumn = 11 + , lpStartByte = 245 + , lpLength = 4 + } + } + ] + , expr_annot = + LP + { lpLine = 20 + , lpColumn = 3 + , lpStartByte = 237 + , lpLength = 13 + } + } + , stmt_annot = + LP + { lpLine = 20 + , lpColumn = 3 + , lpStartByte = 237 + , lpLength = 14 + } + } + ] + , stmt_annot = + LP + { lpLine = 19 , lpColumn = 17 , lpStartByte = 233 , lpLength = 20 } + } + , stmt_else = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "a is not b" + , literal_annot = + LP + { lpLine = 22 + , lpColumn = 11 + , lpStartByte = 271 + , lpLength = 12 + } + } + , expr_annot = + LP + { lpLine = 22 + , lpColumn = 11 + , lpStartByte = 271 + , lpLength = 12 + } + } + ] + , expr_annot = + LP + { lpLine = 22 + , lpColumn = 3 + , lpStartByte = 263 + , lpLength = 21 + } + } + , stmt_annot = + LP + { lpLine = 22 + , lpColumn = 3 + , lpStartByte = 263 + , lpLength = 22 + } + } + ] + , stmt_annot = LP - { lpLine = 26 , lpColumn = 11 , lpStartByte = 327 , lpLength = 11 } - ] - ) + { lpLine = 21 , lpColumn = 8 , lpStartByte = 259 , lpLength = 28 } + } + , stmt_annot = LP - { lpLine = 26 , lpColumn = 3 , lpStartByte = 319 , lpLength = 20 }) - LP - { lpLine = 26 , lpColumn = 3 , lpStartByte = 319 , lpLength = 21 } - ] - LP - { lpLine = 25 , lpColumn = 18 , lpStartByte = 315 , lpLength = 27 } - ) - LP - { lpLine = 25 , lpColumn = 1 , lpStartByte = 298 , lpLength = 44 }) - LP - { lpLine = 25 , lpColumn = 1 , lpStartByte = 298 , lpLength = 44 } - , Statement - (If - ( Binary - ( ArithEqual - LP - { lpLine = 28 , lpColumn = 10 , lpStartByte = 352 , lpLength = 3 } - , Literal - (String - "43" + { lpLine = 19 , lpColumn = 1 , lpStartByte = 217 , lpLength = 70 } + } + , toplevel_annot = + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 217 , lpLength = 70 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 3 } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 43 + , literal_annot = + LP + { lpLine = 24 + , lpColumn = 7 + , lpStartByte = 294 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 24 , lpColumn = 7 , lpStartByte = 294 , lpLength = 2 } + } + , expr_annot = + LP + { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 8 } + } + , stmt_annot = LP - { lpLine = 28 , lpColumn = 5 , lpStartByte = 347 , lpLength = 4 }) - LP - { lpLine = 28 , lpColumn = 5 , lpStartByte = 347 , lpLength = 4 } - , LeftValue - (Identifier - "num" + { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 9 } + } + , toplevel_annot = + LP + { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 9 } + } + , Statement + { toplevel_stmt = + If + { stmt_expr = + Binary + { expr_binOp = + Equal + { binOp_annot = + LP + { lpLine = 25 , lpColumn = 10 , lpStartByte = 307 , lpLength = 2 } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "43" + , literal_annot = + LP + { lpLine = 25 + , lpColumn = 5 + , lpStartByte = 302 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 25 , lpColumn = 5 , lpStartByte = 302 , lpLength = 4 } + } + , expr_right = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 25 + , lpColumn = 13 + , lpStartByte = 310 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 25 , lpColumn = 13 , lpStartByte = 310 , lpLength = 3 } + } + , expr_annot = + LP + { lpLine = 25 , lpColumn = 5 , lpStartByte = 302 , lpLength = 11 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "43 == num" + , literal_annot = + LP + { lpLine = 26 + , lpColumn = 11 + , lpStartByte = 327 + , lpLength = 11 + } + } + , expr_annot = + LP + { lpLine = 26 + , lpColumn = 11 + , lpStartByte = 327 + , lpLength = 11 + } + } + ] + , expr_annot = + LP + { lpLine = 26 + , lpColumn = 3 + , lpStartByte = 319 + , lpLength = 20 + } + } + , stmt_annot = + LP + { lpLine = 26 + , lpColumn = 3 + , lpStartByte = 319 + , lpLength = 21 + } + } + ] + , stmt_annot = + LP + { lpLine = 25 , lpColumn = 18 , lpStartByte = 315 , lpLength = 27 } + } + , stmt_annot = LP - { lpLine = 28 , lpColumn = 14 , lpStartByte = 356 , lpLength = 3 }) - LP - { lpLine = 28 , lpColumn = 14 , lpStartByte = 356 , lpLength = 3 } - ) - LP - { lpLine = 28 , lpColumn = 5 , lpStartByte = 347 , lpLength = 12 } - , Block - [ Expression - (Call - ( "println" - , [ Literal - (String - "43 === num" - LP - { lpLine = 29 - , lpColumn = 11 - , lpStartByte = 373 - , lpLength = 12 - }) + { lpLine = 25 , lpColumn = 1 , lpStartByte = 298 , lpLength = 44 } + } + , toplevel_annot = + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 298 , lpLength = 44 } + } + , Statement + { toplevel_stmt = + If + { stmt_expr = + Binary + { expr_binOp = + ArithEqual + { binOp_annot = + LP + { lpLine = 28 , lpColumn = 10 , lpStartByte = 352 , lpLength = 3 } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "43" + , literal_annot = + LP + { lpLine = 28 + , lpColumn = 5 + , lpStartByte = 347 + , lpLength = 4 + } + } + , expr_annot = + LP + { lpLine = 28 , lpColumn = 5 , lpStartByte = 347 , lpLength = 4 } + } + , expr_right = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 28 + , lpColumn = 14 + , lpStartByte = 356 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 28 , lpColumn = 14 , lpStartByte = 356 , lpLength = 3 } + } + , expr_annot = + LP + { lpLine = 28 , lpColumn = 5 , lpStartByte = 347 , lpLength = 12 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "43 === num" + , literal_annot = + LP + { lpLine = 29 + , lpColumn = 11 + , lpStartByte = 373 + , lpLength = 12 + } + } + , expr_annot = + LP + { lpLine = 29 + , lpColumn = 11 + , lpStartByte = 373 + , lpLength = 12 + } + } + ] + , expr_annot = + LP + { lpLine = 29 + , lpColumn = 3 + , lpStartByte = 365 + , lpLength = 21 + } + } + , stmt_annot = + LP + { lpLine = 29 + , lpColumn = 3 + , lpStartByte = 365 + , lpLength = 22 + } + } + ] + , stmt_annot = LP - { lpLine = 29 , lpColumn = 11 , lpStartByte = 373 , lpLength = 12 } - ] - ) + { lpLine = 28 , lpColumn = 19 , lpStartByte = 361 , lpLength = 28 } + } + , stmt_annot = LP - { lpLine = 29 , lpColumn = 3 , lpStartByte = 365 , lpLength = 21 }) - LP - { lpLine = 29 , lpColumn = 3 , lpStartByte = 365 , lpLength = 22 } - ] - LP - { lpLine = 28 , lpColumn = 19 , lpStartByte = 361 , lpLength = 28 } - ) - LP - { lpLine = 28 , lpColumn = 1 , lpStartByte = 343 , lpLength = 46 }) - LP - { lpLine = 28 , lpColumn = 1 , lpStartByte = 343 , lpLength = 46 } - ] - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 389 } + { lpLine = 28 , lpColumn = 1 , lpStartByte = 343 , lpLength = 46 } + } + , toplevel_annot = + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 343 , lpLength = 46 } + } + ] + , program_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 389 } + } diff --git a/test/testcase/Batsh/recursion.ast b/test/testcase/Batsh/recursion.ast index 8b5ab74..963ca68 100644 --- a/test/testcase/Batsh/recursion.ast +++ b/test/testcase/Batsh/recursion.ast @@ -1,611 +1,1209 @@ Program - [ Statement - (Comment - " Loop" - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 7 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 7 } - , Function - ( "loop" - , [ "num" ] - , [ Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "num" - LP - { lpLine = 3 , lpColumn = 11 , lpStartByte = 39 , lpLength = 3 }) - LP { lpLine = 3 , lpColumn = 11 , lpStartByte = 39 , lpLength = 3 } - ] - ) - LP - { lpLine = 3 , lpColumn = 3 , lpStartByte = 31 , lpLength = 12 }) - LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 31 , lpLength = 13 } - , If - ( Binary - ( Greater - LP { lpLine = 4 , lpColumn = 11 , lpStartByte = 55 , lpLength = 1 } - , LeftValue - (Identifier - "num" - LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 51 , lpLength = 3 }) - LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 51 , lpLength = 3 } - , Literal - (Int - 0 - LP - { lpLine = 4 , lpColumn = 13 , lpStartByte = 57 , lpLength = 1 }) - LP { lpLine = 4 , lpColumn = 13 , lpStartByte = 57 , lpLength = 1 } - ) - LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 51 , lpLength = 7 } - , Block - [ Expression - (Call - ( "loop" - , [ Binary - ( Minus - LP { lpLine = 5 , lpColumn = 14 , lpStartByte = 75 , lpLength = 1 } - , LeftValue - (Identifier - "num" + { program_topls = + [ Statement + { toplevel_stmt = + Comment + { stmt_comment = " Loop" + , stmt_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 7 } + } + , toplevel_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 7 } + } + , Function + { toplevel_func = "loop" + , toplevel_params = [ "num" ] + , toplevel_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 39 + , lpLength = 3 + } + } + , expr_annot = LP - { lpLine = 5 - , lpColumn = 10 - , lpStartByte = 71 + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 39 , lpLength = 3 - }) - LP { lpLine = 5 , lpColumn = 10 , lpStartByte = 71 , lpLength = 3 } - , Literal - (Int - 1 + } + } + ] + , expr_annot = + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 31 , lpLength = 12 } + } + , stmt_annot = + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 31 , lpLength = 13 } + } + , If + { stmt_expr = + Binary + { expr_binOp = + Greater + { binOp_annot = + LP + { lpLine = 4 , lpColumn = 11 , lpStartByte = 55 , lpLength = 1 } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 4 + , lpColumn = 7 + , lpStartByte = 51 + , lpLength = 3 + } + } + , expr_annot = + LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 51 , lpLength = 3 } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + LP + { lpLine = 4 + , lpColumn = 13 + , lpStartByte = 57 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 4 , lpColumn = 13 , lpStartByte = 57 , lpLength = 1 } + } + , expr_annot = + LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 51 , lpLength = 7 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "loop" + , expr_params = + [ Binary + { expr_binOp = + Minus + { binOp_annot = + LP + { lpLine = 5 + , lpColumn = 14 + , lpStartByte = 75 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 5 + , lpColumn = 10 + , lpStartByte = 71 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 10 + , lpStartByte = 71 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 16 + , lpStartByte = 77 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 16 + , lpStartByte = 77 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 10 + , lpStartByte = 71 + , lpLength = 7 + } + } + ] + , expr_annot = + LP + { lpLine = 5 + , lpColumn = 5 + , lpStartByte = 66 + , lpLength = 13 + } + } + , stmt_annot = LP { lpLine = 5 - , lpColumn = 16 - , lpStartByte = 77 - , lpLength = 1 - }) - LP { lpLine = 5 , lpColumn = 16 , lpStartByte = 77 , lpLength = 1 } - ) - LP { lpLine = 5 , lpColumn = 10 , lpStartByte = 71 , lpLength = 7 } - ] - ) - LP - { lpLine = 5 , lpColumn = 5 , lpStartByte = 66 , lpLength = 13 }) - LP { lpLine = 5 , lpColumn = 5 , lpStartByte = 66 , lpLength = 14 } - ] - LP - { lpLine = 4 , lpColumn = 16 , lpStartByte = 60 , lpLength = 24 } - ) - LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 47 , lpLength = 37 } - ] - ) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 8 , lpLength = 78 } - , Statement - (Expression - (Call - ( "loop" - , [ Literal - (Int - 10 - LP { lpLine = 8 , lpColumn = 6 , lpStartByte = 92 , lpLength = 2 }) - LP { lpLine = 8 , lpColumn = 6 , lpStartByte = 92 , lpLength = 2 } + , lpColumn = 5 + , lpStartByte = 66 + , lpLength = 14 + } + } + ] + , stmt_annot = + LP + { lpLine = 4 , lpColumn = 16 , lpStartByte = 60 , lpLength = 24 } + } + , stmt_annot = + LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 47 , lpLength = 37 } + } ] - ) - LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 87 , lpLength = 8 }) - LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 87 , lpLength = 9 }) - LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 87 , lpLength = 9 } - , Statement - (Comment - " Factorial" - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 97 , lpLength = 12 }) - LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 97 , lpLength = 12 } - , Function - ( "fact" - , [ "num" ] - , [ IfElse - ( Binary - ( ArithEqual - LP - { lpLine = 11 , lpColumn = 11 , lpStartByte = 141 , lpLength = 3 } - , LeftValue - (Identifier - "num" - LP - { lpLine = 11 , lpColumn = 7 , lpStartByte = 137 , lpLength = 3 }) - LP - { lpLine = 11 , lpColumn = 7 , lpStartByte = 137 , lpLength = 3 } - , Literal - (Int - 0 - LP - { lpLine = 11 , lpColumn = 15 , lpStartByte = 145 , lpLength = 1 }) - LP - { lpLine = 11 , lpColumn = 15 , lpStartByte = 145 , lpLength = 1 } - ) - LP - { lpLine = 11 , lpColumn = 7 , lpStartByte = 137 , lpLength = 9 } - , Block - [ Return - (Just - (Literal - (Int - 1 - LP - { lpLine = 12 , lpColumn = 12 , lpStartByte = 161 , lpLength = 1 }) - LP - { lpLine = 12 - , lpColumn = 12 - , lpStartByte = 161 - , lpLength = 1 - })) - LP - { lpLine = 12 , lpColumn = 5 , lpStartByte = 154 , lpLength = 9 } - ] - LP - { lpLine = 11 , lpColumn = 18 , lpStartByte = 148 , lpLength = 19 } - , Block - [ Return - (Just - (Binary - ( Multiply - LP - { lpLine = 14 , lpColumn = 26 , lpStartByte = 200 , lpLength = 1 } - , Call - ( "fact" - , [ Binary - ( Minus + , toplevel_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 8 , lpLength = 78 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "loop" + , expr_params = + [ Literal + { expr_literal = + Int + { literal_int = 10 + , literal_annot = LP - { lpLine = 14 - , lpColumn = 21 - , lpStartByte = 195 - , lpLength = 1 + { lpLine = 8 + , lpColumn = 6 + , lpStartByte = 92 + , lpLength = 2 } - , LeftValue - (Identifier - "num" - LP - { lpLine = 14 - , lpColumn = 17 - , lpStartByte = 191 - , lpLength = 3 - }) + } + , expr_annot = + LP { lpLine = 8 , lpColumn = 6 , lpStartByte = 92 , lpLength = 2 } + } + ] + , expr_annot = + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 87 , lpLength = 8 } + } + , stmt_annot = + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 87 , lpLength = 9 } + } + , toplevel_annot = + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 87 , lpLength = 9 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " Factorial" + , stmt_annot = + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 97 , lpLength = 12 } + } + , toplevel_annot = + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 97 , lpLength = 12 } + } + , Function + { toplevel_func = "fact" + , toplevel_params = [ "num" ] + , toplevel_stmts = + [ IfElse + { stmt_expr = + Binary + { expr_binOp = + ArithEqual + { binOp_annot = + LP + { lpLine = 11 + , lpColumn = 11 + , lpStartByte = 141 + , lpLength = 3 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = LP - { lpLine = 14 - , lpColumn = 17 - , lpStartByte = 191 + { lpLine = 11 + , lpColumn = 7 + , lpStartByte = 137 , lpLength = 3 } - , Literal - (Int - 1 - LP - { lpLine = 14 - , lpColumn = 23 - , lpStartByte = 197 - , lpLength = 1 - }) + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 7 + , lpStartByte = 137 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = LP - { lpLine = 14 - , lpColumn = 23 - , lpStartByte = 197 + { lpLine = 11 + , lpColumn = 15 + , lpStartByte = 145 , lpLength = 1 } - ) + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 15 + , lpStartByte = 145 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 11 , lpColumn = 7 , lpStartByte = 137 , lpLength = 9 } + } + , stmt_then = + Block + { stmt_stmts = + [ Return + { stmt_retval = + Just + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 12 + , lpColumn = 12 + , lpStartByte = 161 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 12 + , lpStartByte = 161 + , lpLength = 1 + } + } + , stmt_annot = + LP + { lpLine = 12 + , lpColumn = 5 + , lpStartByte = 154 + , lpLength = 9 + } + } + ] + , stmt_annot = + LP + { lpLine = 11 , lpColumn = 18 , lpStartByte = 148 , lpLength = 19 } + } + , stmt_else = + Block + { stmt_stmts = + [ Return + { stmt_retval = + Just + Binary + { expr_binOp = + Multiply + { binOp_annot = + LP + { lpLine = 14 + , lpColumn = 26 + , lpStartByte = 200 + , lpLength = 1 + } + } + , expr_left = + Call + { expr_func = "fact" + , expr_params = + [ Binary + { expr_binOp = + Minus + { binOp_annot = + LP + { lpLine = 14 + , lpColumn = 21 + , lpStartByte = 195 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 14 + , lpColumn = 17 + , lpStartByte = 191 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 14 + , lpColumn = 17 + , lpStartByte = 191 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 14 + , lpColumn = 23 + , lpStartByte = 197 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 14 + , lpColumn = 23 + , lpStartByte = 197 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 14 + , lpColumn = 17 + , lpStartByte = 191 + , lpLength = 7 + } + } + ] + , expr_annot = + LP + { lpLine = 14 + , lpColumn = 12 + , lpStartByte = 186 + , lpLength = 13 + } + } + , expr_right = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 14 + , lpColumn = 28 + , lpStartByte = 202 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 14 + , lpColumn = 28 + , lpStartByte = 202 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 14 + , lpColumn = 12 + , lpStartByte = 186 + , lpLength = 19 + } + } + , stmt_annot = LP { lpLine = 14 - , lpColumn = 17 - , lpStartByte = 191 - , lpLength = 7 + , lpColumn = 5 + , lpStartByte = 179 + , lpLength = 27 } - ] - ) - LP - { lpLine = 14 , lpColumn = 12 , lpStartByte = 186 , lpLength = 13 } - , LeftValue - (Identifier - "num" - LP - { lpLine = 14 - , lpColumn = 28 - , lpStartByte = 202 - , lpLength = 3 - }) - LP - { lpLine = 14 , lpColumn = 28 , lpStartByte = 202 , lpLength = 3 } - ) - LP - { lpLine = 14 - , lpColumn = 12 - , lpStartByte = 186 - , lpLength = 19 - })) - LP - { lpLine = 14 , lpColumn = 5 , lpStartByte = 179 , lpLength = 27 } - ] - LP - { lpLine = 13 , lpColumn = 10 , lpStartByte = 173 , lpLength = 37 } - ) - LP - { lpLine = 11 , lpColumn = 3 , lpStartByte = 133 , lpLength = 77 } - ] - ) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 110 , lpLength = 102 } - , Statement - (Expression - (Call - ( "println" - , [ Call - ( "fact" - , [ Literal - (Int - 5 - LP - { lpLine = 17 , lpColumn = 14 , lpStartByte = 226 , lpLength = 1 }) - LP - { lpLine = 17 , lpColumn = 14 , lpStartByte = 226 , lpLength = 1 } - ] - ) - LP - { lpLine = 17 , lpColumn = 9 , lpStartByte = 221 , lpLength = 7 } + } + ] + , stmt_annot = + LP + { lpLine = 13 , lpColumn = 10 , lpStartByte = 173 , lpLength = 37 } + } + , stmt_annot = + LP + { lpLine = 11 , lpColumn = 3 , lpStartByte = 133 , lpLength = 77 } + } ] - ) - LP - { lpLine = 17 , lpColumn = 1 , lpStartByte = 213 , lpLength = 16 }) - LP - { lpLine = 17 , lpColumn = 1 , lpStartByte = 213 , lpLength = 17 }) - LP - { lpLine = 17 , lpColumn = 1 , lpStartByte = 213 , lpLength = 17 } - , Statement - (Comment - " Fibonacci" - LP - { lpLine = 18 , lpColumn = 1 , lpStartByte = 231 , lpLength = 12 }) - LP - { lpLine = 18 , lpColumn = 1 , lpStartByte = 231 , lpLength = 12 } - , Function - ( "fibonacci" - , [ "num" ] - , [ IfElse - ( Binary - ( ArithEqual - LP - { lpLine = 20 , lpColumn = 11 , lpStartByte = 280 , lpLength = 3 } - , LeftValue - (Identifier - "num" - LP - { lpLine = 20 , lpColumn = 7 , lpStartByte = 276 , lpLength = 3 }) - LP - { lpLine = 20 , lpColumn = 7 , lpStartByte = 276 , lpLength = 3 } - , Literal - (Int - 0 - LP - { lpLine = 20 , lpColumn = 15 , lpStartByte = 284 , lpLength = 1 }) - LP - { lpLine = 20 , lpColumn = 15 , lpStartByte = 284 , lpLength = 1 } - ) - LP - { lpLine = 20 , lpColumn = 7 , lpStartByte = 276 , lpLength = 9 } - , Block - [ Return - (Just - (Literal - (Int - 0 - LP - { lpLine = 21 , lpColumn = 12 , lpStartByte = 300 , lpLength = 1 }) + , toplevel_annot = + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 110 , lpLength = 102 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Call + { expr_func = "fact" + , expr_params = + [ Literal + { expr_literal = + Int + { literal_int = 5 + , literal_annot = + LP + { lpLine = 17 + , lpColumn = 14 + , lpStartByte = 226 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 17 + , lpColumn = 14 + , lpStartByte = 226 + , lpLength = 1 + } + } + ] + , expr_annot = + LP + { lpLine = 17 + , lpColumn = 9 + , lpStartByte = 221 + , lpLength = 7 + } + } + ] + , expr_annot = LP - { lpLine = 21 - , lpColumn = 12 - , lpStartByte = 300 - , lpLength = 1 - })) - LP - { lpLine = 21 , lpColumn = 5 , lpStartByte = 293 , lpLength = 9 } - ] - LP - { lpLine = 20 , lpColumn = 18 , lpStartByte = 287 , lpLength = 19 } - , IfElse - ( Binary - ( ArithEqual - LP - { lpLine = 22 , lpColumn = 18 , lpStartByte = 320 , lpLength = 3 } - , LeftValue - (Identifier - "num" - LP - { lpLine = 22 , lpColumn = 14 , lpStartByte = 316 , lpLength = 3 }) - LP - { lpLine = 22 , lpColumn = 14 , lpStartByte = 316 , lpLength = 3 } - , Literal - (Int - 1 - LP - { lpLine = 22 , lpColumn = 22 , lpStartByte = 324 , lpLength = 1 }) - LP - { lpLine = 22 , lpColumn = 22 , lpStartByte = 324 , lpLength = 1 } - ) + { lpLine = 17 , lpColumn = 1 , lpStartByte = 213 , lpLength = 16 } + } + , stmt_annot = LP - { lpLine = 22 , lpColumn = 14 , lpStartByte = 316 , lpLength = 9 } - , Block - [ Return - (Just - (Literal - (Int - 1 - LP - { lpLine = 23 - , lpColumn = 12 - , lpStartByte = 340 - , lpLength = 1 - }) - LP - { lpLine = 23 - , lpColumn = 12 - , lpStartByte = 340 - , lpLength = 1 - })) - LP - { lpLine = 23 , lpColumn = 5 , lpStartByte = 333 , lpLength = 9 } - ] + { lpLine = 17 , lpColumn = 1 , lpStartByte = 213 , lpLength = 17 } + } + , toplevel_annot = + LP + { lpLine = 17 , lpColumn = 1 , lpStartByte = 213 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " Fibonacci" + , stmt_annot = LP - { lpLine = 22 , lpColumn = 25 , lpStartByte = 327 , lpLength = 19 } - , Block - [ Return - (Just - (Binary - ( Plus + { lpLine = 18 , lpColumn = 1 , lpStartByte = 231 , lpLength = 12 } + } + , toplevel_annot = + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 231 , lpLength = 12 } + } + , Function + { toplevel_func = "fibonacci" + , toplevel_params = [ "num" ] + , toplevel_stmts = + [ IfElse + { stmt_expr = + Binary + { expr_binOp = + ArithEqual + { binOp_annot = + LP + { lpLine = 20 + , lpColumn = 11 + , lpStartByte = 280 + , lpLength = 3 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 20 + , lpColumn = 7 + , lpStartByte = 276 + , lpLength = 3 + } + } + , expr_annot = LP - { lpLine = 25 - , lpColumn = 31 - , lpStartByte = 384 + { lpLine = 20 + , lpColumn = 7 + , lpStartByte = 276 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + LP + { lpLine = 20 + , lpColumn = 15 + , lpStartByte = 284 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 20 + , lpColumn = 15 + , lpStartByte = 284 , lpLength = 1 } - , Call - ( "fibonacci" - , [ Binary - ( Minus - LP - { lpLine = 25 - , lpColumn = 26 - , lpStartByte = 379 - , lpLength = 1 - } - , LeftValue - (Identifier - "num" - LP - { lpLine = 25 - , lpColumn = 22 - , lpStartByte = 375 - , lpLength = 3 - }) - LP - { lpLine = 25 - , lpColumn = 22 - , lpStartByte = 375 - , lpLength = 3 + } + , expr_annot = + LP + { lpLine = 20 , lpColumn = 7 , lpStartByte = 276 , lpLength = 9 } + } + , stmt_then = + Block + { stmt_stmts = + [ Return + { stmt_retval = + Just + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + LP + { lpLine = 21 + , lpColumn = 12 + , lpStartByte = 300 + , lpLength = 1 + } } - , Literal - (Int - 2 - LP - { lpLine = 25 - , lpColumn = 28 - , lpStartByte = 381 - , lpLength = 1 - }) + , expr_annot = LP - { lpLine = 25 - , lpColumn = 28 - , lpStartByte = 381 + { lpLine = 21 + , lpColumn = 12 + , lpStartByte = 300 , lpLength = 1 } - ) + } + , stmt_annot = + LP + { lpLine = 21 + , lpColumn = 5 + , lpStartByte = 293 + , lpLength = 9 + } + } + ] + , stmt_annot = + LP + { lpLine = 20 , lpColumn = 18 , lpStartByte = 287 , lpLength = 19 } + } + , stmt_else = + IfElse + { stmt_expr = + Binary + { expr_binOp = + ArithEqual + { binOp_annot = LP - { lpLine = 25 + { lpLine = 22 + , lpColumn = 18 + , lpStartByte = 320 + , lpLength = 3 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 22 + , lpColumn = 14 + , lpStartByte = 316 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 22 + , lpColumn = 14 + , lpStartByte = 316 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 22 + , lpColumn = 22 + , lpStartByte = 324 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 22 , lpColumn = 22 - , lpStartByte = 375 - , lpLength = 7 + , lpStartByte = 324 + , lpLength = 1 } - ] - ) + } + , expr_annot = LP - { lpLine = 25 - , lpColumn = 12 - , lpStartByte = 365 - , lpLength = 18 + { lpLine = 22 + , lpColumn = 14 + , lpStartByte = 316 + , lpLength = 9 } - , Call - ( "fibonacci" - , [ Binary - ( Minus - LP - { lpLine = 25 - , lpColumn = 47 - , lpStartByte = 400 - , lpLength = 1 + } + , stmt_then = + Block + { stmt_stmts = + [ Return + { stmt_retval = + Just + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 23 + , lpColumn = 12 + , lpStartByte = 340 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 23 + , lpColumn = 12 + , lpStartByte = 340 + , lpLength = 1 + } } - , LeftValue - (Identifier - "num" - LP - { lpLine = 25 - , lpColumn = 43 - , lpStartByte = 396 - , lpLength = 3 - }) - LP - { lpLine = 25 - , lpColumn = 43 - , lpStartByte = 396 - , lpLength = 3 - } - , Literal - (Int - 1 - LP - { lpLine = 25 - , lpColumn = 49 - , lpStartByte = 402 - , lpLength = 1 - }) - LP - { lpLine = 25 - , lpColumn = 49 - , lpStartByte = 402 - , lpLength = 1 + , stmt_annot = + LP + { lpLine = 23 + , lpColumn = 5 + , lpStartByte = 333 + , lpLength = 9 + } + } + ] + , stmt_annot = + LP + { lpLine = 22 + , lpColumn = 25 + , lpStartByte = 327 + , lpLength = 19 + } + } + , stmt_else = + Block + { stmt_stmts = + [ Return + { stmt_retval = + Just + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 25 + , lpColumn = 31 + , lpStartByte = 384 + , lpLength = 1 + } + } + , expr_left = + Call + { expr_func = "fibonacci" + , expr_params = + [ Binary + { expr_binOp = + Minus + { binOp_annot = + LP + { lpLine = 25 + , lpColumn = 26 + , lpStartByte = 379 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 25 + , lpColumn = 22 + , lpStartByte = 375 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 25 + , lpColumn = 22 + , lpStartByte = 375 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 25 + , lpColumn = 28 + , lpStartByte = 381 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 25 + , lpColumn = 28 + , lpStartByte = 381 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 25 + , lpColumn = 22 + , lpStartByte = 375 + , lpLength = 7 + } + } + ] + , expr_annot = + LP + { lpLine = 25 + , lpColumn = 12 + , lpStartByte = 365 + , lpLength = 18 + } + } + , expr_right = + Call + { expr_func = "fibonacci" + , expr_params = + [ Binary + { expr_binOp = + Minus + { binOp_annot = + LP + { lpLine = 25 + , lpColumn = 47 + , lpStartByte = 400 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + LP + { lpLine = 25 + , lpColumn = 43 + , lpStartByte = 396 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 25 + , lpColumn = 43 + , lpStartByte = 396 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 25 + , lpColumn = 49 + , lpStartByte = 402 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 25 + , lpColumn = 49 + , lpStartByte = 402 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 25 + , lpColumn = 43 + , lpStartByte = 396 + , lpLength = 7 + } + } + ] + , expr_annot = + LP + { lpLine = 25 + , lpColumn = 33 + , lpStartByte = 386 + , lpLength = 18 + } + } + , expr_annot = + LP + { lpLine = 25 + , lpColumn = 12 + , lpStartByte = 365 + , lpLength = 39 + } } - ) - LP - { lpLine = 25 - , lpColumn = 43 - , lpStartByte = 396 - , lpLength = 7 - } - ] - ) + , stmt_annot = + LP + { lpLine = 25 + , lpColumn = 5 + , lpStartByte = 358 + , lpLength = 47 + } + } + ] + , stmt_annot = LP - { lpLine = 25 - , lpColumn = 33 - , lpStartByte = 386 - , lpLength = 18 + { lpLine = 24 + , lpColumn = 10 + , lpStartByte = 352 + , lpLength = 57 } - ) - LP - { lpLine = 25 - , lpColumn = 12 - , lpStartByte = 365 - , lpLength = 39 - })) - LP - { lpLine = 25 , lpColumn = 5 , lpStartByte = 358 , lpLength = 47 } - ] - LP - { lpLine = 24 , lpColumn = 10 , lpStartByte = 352 , lpLength = 57 } - ) - LP - { lpLine = 22 , lpColumn = 10 , lpStartByte = 312 , lpLength = 97 } - ) - LP - { lpLine = 20 , lpColumn = 3 , lpStartByte = 272 , lpLength = 137 } - ] - ) - LP - { lpLine = 19 , lpColumn = 1 , lpStartByte = 244 , lpLength = 167 } - , Statement - (Expression - (Assign - ( Identifier - "i" - LP - { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 1 } - , Literal - (Int - 0 - LP - { lpLine = 28 , lpColumn = 5 , lpStartByte = 416 , lpLength = 1 }) - LP - { lpLine = 28 , lpColumn = 5 , lpStartByte = 416 , lpLength = 1 } - ) - LP - { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 5 }) - LP - { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 6 }) - LP - { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 6 } - , Statement - (While - ( Binary - ( Less - LP - { lpLine = 29 , lpColumn = 10 , lpStartByte = 428 , lpLength = 1 } - , LeftValue - (Identifier - "i" - LP - { lpLine = 29 , lpColumn = 8 , lpStartByte = 426 , lpLength = 1 }) - LP - { lpLine = 29 , lpColumn = 8 , lpStartByte = 426 , lpLength = 1 } - , Literal - (Int - 7 - LP - { lpLine = 29 , lpColumn = 12 , lpStartByte = 430 , lpLength = 1 }) - LP - { lpLine = 29 , lpColumn = 12 , lpStartByte = 430 , lpLength = 1 } - ) - LP - { lpLine = 29 , lpColumn = 8 , lpStartByte = 426 , lpLength = 5 } - , Block - [ Expression - (Call - ( "println" - , [ Call - ( "fibonacci" - , [ LeftValue - (Identifier - "i" - LP - { lpLine = 30 - , lpColumn = 21 - , lpStartByte = 455 - , lpLength = 1 - }) + } + , stmt_annot = + LP + { lpLine = 22 , lpColumn = 10 , lpStartByte = 312 , lpLength = 97 } + } + , stmt_annot = + LP + { lpLine = 20 , lpColumn = 3 , lpStartByte = 272 , lpLength = 137 } + } + ] + , toplevel_annot = + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 244 , lpLength = 167 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = LP - { lpLine = 30 , lpColumn = 21 , lpStartByte = 455 , lpLength = 1 } - ] - ) + { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + LP + { lpLine = 28 + , lpColumn = 5 + , lpStartByte = 416 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 28 , lpColumn = 5 , lpStartByte = 416 , lpLength = 1 } + } + , expr_annot = LP - { lpLine = 30 , lpColumn = 11 , lpStartByte = 445 , lpLength = 12 } - ] - ) + { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 5 } + } + , stmt_annot = LP - { lpLine = 30 , lpColumn = 3 , lpStartByte = 437 , lpLength = 21 }) - LP - { lpLine = 30 , lpColumn = 3 , lpStartByte = 437 , lpLength = 22 } - , Expression - (Assign - ( Identifier - "i" - LP - { lpLine = 31 , lpColumn = 3 , lpStartByte = 462 , lpLength = 1 } - , Binary - ( Plus - LP - { lpLine = 31 , lpColumn = 9 , lpStartByte = 468 , lpLength = 1 } - , LeftValue - (Identifier - "i" - LP - { lpLine = 31 , lpColumn = 7 , lpStartByte = 466 , lpLength = 1 }) - LP - { lpLine = 31 , lpColumn = 7 , lpStartByte = 466 , lpLength = 1 } - , Literal - (Int - 1 - LP - { lpLine = 31 , lpColumn = 11 , lpStartByte = 470 , lpLength = 1 }) - LP - { lpLine = 31 , lpColumn = 11 , lpStartByte = 470 , lpLength = 1 } - ) - LP - { lpLine = 31 , lpColumn = 7 , lpStartByte = 466 , lpLength = 5 } - ) + { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 6 } + } + , toplevel_annot = + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + While + { stmt_expr = + Binary + { expr_binOp = + Less + { binOp_annot = + LP + { lpLine = 29 , lpColumn = 10 , lpStartByte = 428 , lpLength = 1 } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + LP + { lpLine = 29 + , lpColumn = 8 + , lpStartByte = 426 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 29 , lpColumn = 8 , lpStartByte = 426 , lpLength = 1 } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 7 + , literal_annot = + LP + { lpLine = 29 + , lpColumn = 12 + , lpStartByte = 430 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 29 , lpColumn = 12 , lpStartByte = 430 , lpLength = 1 } + } + , expr_annot = + LP + { lpLine = 29 , lpColumn = 8 , lpStartByte = 426 , lpLength = 5 } + } + , stmt_loop = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Call + { expr_func = "fibonacci" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + LP + { lpLine = 30 + , lpColumn = 21 + , lpStartByte = 455 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 30 + , lpColumn = 21 + , lpStartByte = 455 + , lpLength = 1 + } + } + ] + , expr_annot = + LP + { lpLine = 30 + , lpColumn = 11 + , lpStartByte = 445 + , lpLength = 12 + } + } + ] + , expr_annot = + LP + { lpLine = 30 + , lpColumn = 3 + , lpStartByte = 437 + , lpLength = 21 + } + } + , stmt_annot = + LP + { lpLine = 30 + , lpColumn = 3 + , lpStartByte = 437 + , lpLength = 22 + } + } + , Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + LP + { lpLine = 31 + , lpColumn = 3 + , lpStartByte = 462 + , lpLength = 1 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 31 + , lpColumn = 9 + , lpStartByte = 468 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + LP + { lpLine = 31 + , lpColumn = 7 + , lpStartByte = 466 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 31 + , lpColumn = 7 + , lpStartByte = 466 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 31 + , lpColumn = 11 + , lpStartByte = 470 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 31 + , lpColumn = 11 + , lpStartByte = 470 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 31 + , lpColumn = 7 + , lpStartByte = 466 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 31 + , lpColumn = 3 + , lpStartByte = 462 + , lpLength = 9 + } + } + , stmt_annot = + LP + { lpLine = 31 + , lpColumn = 3 + , lpStartByte = 462 + , lpLength = 10 + } + } + ] + , stmt_annot = + LP + { lpLine = 29 , lpColumn = 15 , lpStartByte = 433 , lpLength = 41 } + } + , stmt_annot = LP - { lpLine = 31 , lpColumn = 3 , lpStartByte = 462 , lpLength = 9 }) - LP - { lpLine = 31 , lpColumn = 3 , lpStartByte = 462 , lpLength = 10 } - ] - LP - { lpLine = 29 , lpColumn = 15 , lpStartByte = 433 , lpLength = 41 } - ) - LP - { lpLine = 29 , lpColumn = 1 , lpStartByte = 419 , lpLength = 55 }) - LP - { lpLine = 29 , lpColumn = 1 , lpStartByte = 419 , lpLength = 55 } - ] - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 474 } + { lpLine = 29 , lpColumn = 1 , lpStartByte = 419 , lpLength = 55 } + } + , toplevel_annot = + LP + { lpLine = 29 , lpColumn = 1 , lpStartByte = 419 , lpLength = 55 } + } + ] + , program_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 474 } + } diff --git a/test/testcase/Batsh/string.ast b/test/testcase/Batsh/string.ast index ee97cf0..fe5b3fb 100644 --- a/test/testcase/Batsh/string.ast +++ b/test/testcase/Batsh/string.ast @@ -1,399 +1,966 @@ Program - [ Statement - (Expression - (Call - ( "println" - , [ Literal - (String - "BYVoid" - LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 8 }) - LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 8 } - ] - ) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 17 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 18 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 18 } - , Statement - (Expression - (Call - ( "println" - , [ Literal - (String - "Slash/" - LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 27 , lpLength = 8 }) - LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 27 , lpLength = 8 } - ] - ) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 19 , lpLength = 17 }) - LP - { lpLine = 2 , lpColumn = 1 , lpStartByte = 19 , lpLength = 18 }) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 19 , lpLength = 18 } - , Statement - (Expression - (Call - ( "println" - , [ Literal - (String - "Backslash\\\\" - LP - { lpLine = 3 , lpColumn = 9 , lpStartByte = 46 , lpLength = 13 }) - LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 46 , lpLength = 13 } - ] - ) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 22 }) - LP - { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 23 }) - LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 23 } - , Statement - (Expression - (Call - ( "println" - , [ Literal - (String - "Quote\\\"'" - LP - { lpLine = 4 , lpColumn = 9 , lpStartByte = 70 , lpLength = 10 }) - LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 70 , lpLength = 10 } - ] - ) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 62 , lpLength = 19 }) - LP - { lpLine = 4 , lpColumn = 1 , lpStartByte = 62 , lpLength = 20 }) - LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 62 , lpLength = 20 } - , Statement - (Expression - (Call - ( "println" - , [ Literal - (String - "Tab\\tTab" - LP - { lpLine = 5 , lpColumn = 9 , lpStartByte = 91 , lpLength = 10 }) - LP { lpLine = 5 , lpColumn = 9 , lpStartByte = 91 , lpLength = 10 } - ] - ) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 83 , lpLength = 19 }) - LP - { lpLine = 5 , lpColumn = 1 , lpStartByte = 83 , lpLength = 20 }) - LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 83 , lpLength = 20 } - , Statement - (Comment - "println(\"Newline\\nLine2\");" - LP - { lpLine = 6 , lpColumn = 1 , lpStartByte = 104 , lpLength = 28 }) - LP - { lpLine = 6 , lpColumn = 1 , lpStartByte = 104 , lpLength = 28 } - , Statement - (Comment - "println(\"!\");" - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 133 , lpLength = 15 }) - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 133 , lpLength = 15 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Concat - LP - { lpLine = 8 , lpColumn = 41 , lpStartByte = 189 , lpLength = 2 } - , Binary - ( Concat + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "BYVoid" + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 9 + , lpStartByte = 8 + , lpLength = 8 + } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 8 } + } + ] + , expr_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 17 } + } + , stmt_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 18 } + } + , toplevel_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 18 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Slash/" + , literal_annot = + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 27 + , lpLength = 8 + } + } + , expr_annot = + LP { lpLine = 2 , lpColumn = 9 , lpStartByte = 27 , lpLength = 8 } + } + ] + , expr_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 19 , lpLength = 17 } + } + , stmt_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 19 , lpLength = 18 } + } + , toplevel_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 19 , lpLength = 18 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Backslash\\\\" + , literal_annot = + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 46 + , lpLength = 13 + } + } + , expr_annot = + LP + { lpLine = 3 , lpColumn = 9 , lpStartByte = 46 , lpLength = 13 } + } + ] + , expr_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 22 } + } + , stmt_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 23 } + } + , toplevel_annot = + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 23 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Quote\\\"'" + , literal_annot = + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 70 + , lpLength = 10 + } + } + , expr_annot = + LP + { lpLine = 4 , lpColumn = 9 , lpStartByte = 70 , lpLength = 10 } + } + ] + , expr_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 62 , lpLength = 19 } + } + , stmt_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 62 , lpLength = 20 } + } + , toplevel_annot = + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 62 , lpLength = 20 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Tab\\tTab" + , literal_annot = + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 91 + , lpLength = 10 + } + } + , expr_annot = + LP + { lpLine = 5 , lpColumn = 9 , lpStartByte = 91 , lpLength = 10 } + } + ] + , expr_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 83 , lpLength = 19 } + } + , stmt_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 83 , lpLength = 20 } + } + , toplevel_annot = + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 83 , lpLength = 20 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = "println(\"Newline\\nLine2\");" + , stmt_annot = + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 104 , lpLength = 28 } + } + , toplevel_annot = + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 104 , lpLength = 28 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = "println(\"!\");" + , stmt_annot = + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 133 , lpLength = 15 } + } + , toplevel_annot = + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 133 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 8 + , lpColumn = 41 + , lpStartByte = 189 + , lpLength = 2 + } + } + , expr_left = + Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 8 + , lpColumn = 29 + , lpStartByte = 177 + , lpLength = 2 + } + } + , expr_left = + Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 8 + , lpColumn = 19 + , lpStartByte = 167 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "http://" + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 157 + , lpLength = 9 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 157 + , lpLength = 9 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "www." + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 22 + , lpStartByte = 170 + , lpLength = 6 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 22 + , lpStartByte = 170 + , lpLength = 6 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 157 + , lpLength = 19 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "byvoid" + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 32 + , lpStartByte = 180 + , lpLength = 8 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 32 + , lpStartByte = 180 + , lpLength = 8 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 157 + , lpLength = 31 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = ".com" + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 44 + , lpStartByte = 192 + , lpLength = 6 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 44 + , lpStartByte = 192 + , lpLength = 6 + } + } + , expr_annot = + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 157 + , lpLength = 41 + } + } + ] + , expr_annot = LP - { lpLine = 8 , lpColumn = 29 , lpStartByte = 177 , lpLength = 2 } - , Binary - ( Concat - LP - { lpLine = 8 , lpColumn = 19 , lpStartByte = 167 , lpLength = 2 } - , Literal - (String - "http://" - LP - { lpLine = 8 , lpColumn = 9 , lpStartByte = 157 , lpLength = 9 }) - LP { lpLine = 8 , lpColumn = 9 , lpStartByte = 157 , lpLength = 9 } - , Literal - (String - "www." - LP - { lpLine = 8 - , lpColumn = 22 - , lpStartByte = 170 - , lpLength = 6 - }) - LP - { lpLine = 8 , lpColumn = 22 , lpStartByte = 170 , lpLength = 6 } - ) + { lpLine = 8 , lpColumn = 1 , lpStartByte = 149 , lpLength = 50 } + } + , stmt_annot = + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 149 , lpLength = 51 } + } + , toplevel_annot = + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 149 , lpLength = 51 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 9 + , lpColumn = 27 + , lpStartByte = 227 + , lpLength = 2 + } + } + , expr_left = + Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 9 + , lpColumn = 15 + , lpStartByte = 215 + , lpLength = 2 + } + } + , expr_left = + Binary + { expr_binOp = + Divide + { binOp_annot = + LP + { lpLine = 9 + , lpColumn = 11 + , lpStartByte = 211 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 6 + , literal_annot = + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 209 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 209 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + LP + { lpLine = 9 + , lpColumn = 13 + , lpStartByte = 213 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 9 + , lpColumn = 13 + , lpStartByte = 213 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 209 + , lpLength = 5 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "BYVoid" + , literal_annot = + LP + { lpLine = 9 + , lpColumn = 18 + , lpStartByte = 218 + , lpLength = 8 + } + } + , expr_annot = + LP + { lpLine = 9 + , lpColumn = 18 + , lpStartByte = 218 + , lpLength = 8 + } + } + , expr_annot = + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 209 + , lpLength = 17 + } + } + , expr_right = + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 9 + , lpColumn = 32 + , lpStartByte = 232 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 9 + , lpColumn = 30 + , lpStartByte = 230 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 9 + , lpColumn = 30 + , lpStartByte = 230 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 5 + , literal_annot = + LP + { lpLine = 9 + , lpColumn = 34 + , lpStartByte = 234 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 9 + , lpColumn = 34 + , lpStartByte = 234 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 9 + , lpColumn = 30 + , lpStartByte = 230 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 209 + , lpLength = 26 + } + } + ] + , expr_annot = LP - { lpLine = 8 , lpColumn = 9 , lpStartByte = 157 , lpLength = 19 } - , Literal - (String - "byvoid" - LP - { lpLine = 8 , lpColumn = 32 , lpStartByte = 180 , lpLength = 8 }) + { lpLine = 9 , lpColumn = 1 , lpStartByte = 201 , lpLength = 35 } + } + , stmt_annot = + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 201 , lpLength = 36 } + } + , toplevel_annot = + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 201 , lpLength = 36 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 10 + , lpColumn = 11 + , lpStartByte = 248 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 246 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 246 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "3" + , literal_annot = + LP + { lpLine = 10 + , lpColumn = 13 + , lpStartByte = 250 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 13 + , lpStartByte = 250 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 246 + , lpLength = 7 + } + } + ] + , expr_annot = LP - { lpLine = 8 , lpColumn = 32 , lpStartByte = 180 , lpLength = 8 } - ) - LP - { lpLine = 8 , lpColumn = 9 , lpStartByte = 157 , lpLength = 31 } - , Literal - (String - ".com" - LP - { lpLine = 8 , lpColumn = 44 , lpStartByte = 192 , lpLength = 6 }) - LP - { lpLine = 8 , lpColumn = 44 , lpStartByte = 192 , lpLength = 6 } - ) - LP - { lpLine = 8 , lpColumn = 9 , lpStartByte = 157 , lpLength = 41 } - ] - ) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 149 , lpLength = 50 }) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 149 , lpLength = 51 }) - LP - { lpLine = 8 , lpColumn = 1 , lpStartByte = 149 , lpLength = 51 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Concat - LP - { lpLine = 9 , lpColumn = 27 , lpStartByte = 227 , lpLength = 2 } - , Binary - ( Concat + { lpLine = 10 , lpColumn = 1 , lpStartByte = 238 , lpLength = 16 } + } + , stmt_annot = + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 238 , lpLength = 17 } + } + , toplevel_annot = + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 238 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 11 + , lpColumn = 17 + , lpStartByte = 272 + , lpLength = 2 + } + } + , expr_left = + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 11 + , lpColumn = 11 + , lpStartByte = 266 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 264 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 264 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "3" + , literal_annot = + LP + { lpLine = 11 + , lpColumn = 13 + , lpStartByte = 268 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 13 + , lpStartByte = 268 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 264 + , lpLength = 7 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "2" + , literal_annot = + LP + { lpLine = 11 + , lpColumn = 20 + , lpStartByte = 275 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 20 + , lpStartByte = 275 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 264 + , lpLength = 14 + } + } + ] + , expr_annot = LP - { lpLine = 9 , lpColumn = 15 , lpStartByte = 215 , lpLength = 2 } - , Binary - ( Divide - LP - { lpLine = 9 , lpColumn = 11 , lpStartByte = 211 , lpLength = 1 } - , Literal - (Int - 6 - LP - { lpLine = 9 , lpColumn = 9 , lpStartByte = 209 , lpLength = 1 }) - LP { lpLine = 9 , lpColumn = 9 , lpStartByte = 209 , lpLength = 1 } - , Literal - (Int - 2 - LP - { lpLine = 9 - , lpColumn = 13 - , lpStartByte = 213 - , lpLength = 1 - }) - LP - { lpLine = 9 , lpColumn = 13 , lpStartByte = 213 , lpLength = 1 } - ) - LP { lpLine = 9 , lpColumn = 9 , lpStartByte = 209 , lpLength = 5 } - , Literal - (String - "BYVoid" - LP - { lpLine = 9 , lpColumn = 18 , lpStartByte = 218 , lpLength = 8 }) + { lpLine = 11 , lpColumn = 1 , lpStartByte = 256 , lpLength = 23 } + } + , stmt_annot = + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 256 , lpLength = 24 } + } + , toplevel_annot = + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 256 , lpLength = 24 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 12 + , lpColumn = 11 + , lpStartByte = 291 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 289 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 289 + , lpLength = 1 + } + } + , expr_right = + Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 12 + , lpColumn = 18 + , lpStartByte = 298 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "3" + , literal_annot = + LP + { lpLine = 12 + , lpColumn = 14 + , lpStartByte = 294 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 14 + , lpStartByte = 294 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "2" + , literal_annot = + LP + { lpLine = 12 + , lpColumn = 21 + , lpStartByte = 301 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 21 + , lpStartByte = 301 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 14 + , lpStartByte = 294 + , lpLength = 10 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 289 + , lpLength = 15 + } + } + ] + , expr_annot = LP - { lpLine = 9 , lpColumn = 18 , lpStartByte = 218 , lpLength = 8 } - ) - LP - { lpLine = 9 , lpColumn = 9 , lpStartByte = 209 , lpLength = 17 } - , Binary - ( Plus + { lpLine = 12 , lpColumn = 1 , lpStartByte = 281 , lpLength = 25 } + } + , stmt_annot = + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 281 , lpLength = 26 } + } + , toplevel_annot = + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 281 , lpLength = 26 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Equal + { binOp_annot = + LP + { lpLine = 13 + , lpColumn = 18 + , lpStartByte = 325 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "BYVoid" + , literal_annot = + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 316 + , lpLength = 8 + } + } + , expr_annot = + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 316 + , lpLength = 8 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "BYVoid" + , literal_annot = + LP + { lpLine = 13 + , lpColumn = 21 + , lpStartByte = 328 + , lpLength = 8 + } + } + , expr_annot = + LP + { lpLine = 13 + , lpColumn = 21 + , lpStartByte = 328 + , lpLength = 8 + } + } + , expr_annot = + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 316 + , lpLength = 20 + } + } + ] + , expr_annot = LP - { lpLine = 9 , lpColumn = 32 , lpStartByte = 232 , lpLength = 1 } - , Literal - (Int - 3 - LP - { lpLine = 9 , lpColumn = 30 , lpStartByte = 230 , lpLength = 1 }) - LP - { lpLine = 9 , lpColumn = 30 , lpStartByte = 230 , lpLength = 1 } - , Literal - (Int - 5 - LP - { lpLine = 9 , lpColumn = 34 , lpStartByte = 234 , lpLength = 1 }) - LP - { lpLine = 9 , lpColumn = 34 , lpStartByte = 234 , lpLength = 1 } - ) - LP - { lpLine = 9 , lpColumn = 30 , lpStartByte = 230 , lpLength = 5 } - ) - LP - { lpLine = 9 , lpColumn = 9 , lpStartByte = 209 , lpLength = 26 } - ] - ) - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 201 , lpLength = 35 }) - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 201 , lpLength = 36 }) - LP - { lpLine = 9 , lpColumn = 1 , lpStartByte = 201 , lpLength = 36 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Plus - LP - { lpLine = 10 , lpColumn = 11 , lpStartByte = 248 , lpLength = 1 } - , Literal - (Int - 3 - LP - { lpLine = 10 , lpColumn = 9 , lpStartByte = 246 , lpLength = 1 }) - LP - { lpLine = 10 , lpColumn = 9 , lpStartByte = 246 , lpLength = 1 } - , Literal - (String - "3" - LP - { lpLine = 10 , lpColumn = 13 , lpStartByte = 250 , lpLength = 3 }) - LP - { lpLine = 10 , lpColumn = 13 , lpStartByte = 250 , lpLength = 3 } - ) - LP - { lpLine = 10 , lpColumn = 9 , lpStartByte = 246 , lpLength = 7 } - ] - ) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 238 , lpLength = 16 }) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 238 , lpLength = 17 }) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 238 , lpLength = 17 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Concat - LP - { lpLine = 11 , lpColumn = 17 , lpStartByte = 272 , lpLength = 2 } - , Binary - ( Plus - LP - { lpLine = 11 , lpColumn = 11 , lpStartByte = 266 , lpLength = 1 } - , Literal - (Int - 3 - LP - { lpLine = 11 , lpColumn = 9 , lpStartByte = 264 , lpLength = 1 }) - LP - { lpLine = 11 , lpColumn = 9 , lpStartByte = 264 , lpLength = 1 } - , Literal - (String - "3" - LP - { lpLine = 11 , lpColumn = 13 , lpStartByte = 268 , lpLength = 3 }) - LP - { lpLine = 11 , lpColumn = 13 , lpStartByte = 268 , lpLength = 3 } - ) - LP - { lpLine = 11 , lpColumn = 9 , lpStartByte = 264 , lpLength = 7 } - , Literal - (String - "2" - LP - { lpLine = 11 , lpColumn = 20 , lpStartByte = 275 , lpLength = 3 }) - LP - { lpLine = 11 , lpColumn = 20 , lpStartByte = 275 , lpLength = 3 } - ) - LP - { lpLine = 11 , lpColumn = 9 , lpStartByte = 264 , lpLength = 14 } - ] - ) - LP - { lpLine = 11 , lpColumn = 1 , lpStartByte = 256 , lpLength = 23 }) - LP - { lpLine = 11 , lpColumn = 1 , lpStartByte = 256 , lpLength = 24 }) - LP - { lpLine = 11 , lpColumn = 1 , lpStartByte = 256 , lpLength = 24 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Plus - LP - { lpLine = 12 , lpColumn = 11 , lpStartByte = 291 , lpLength = 1 } - , Literal - (Int - 3 - LP - { lpLine = 12 , lpColumn = 9 , lpStartByte = 289 , lpLength = 1 }) - LP - { lpLine = 12 , lpColumn = 9 , lpStartByte = 289 , lpLength = 1 } - , Binary - ( Concat - LP - { lpLine = 12 , lpColumn = 18 , lpStartByte = 298 , lpLength = 2 } - , Literal - (String - "3" - LP - { lpLine = 12 , lpColumn = 14 , lpStartByte = 294 , lpLength = 3 }) - LP - { lpLine = 12 , lpColumn = 14 , lpStartByte = 294 , lpLength = 3 } - , Literal - (String - "2" - LP - { lpLine = 12 , lpColumn = 21 , lpStartByte = 301 , lpLength = 3 }) - LP - { lpLine = 12 , lpColumn = 21 , lpStartByte = 301 , lpLength = 3 } - ) - LP - { lpLine = 12 , lpColumn = 14 , lpStartByte = 294 , lpLength = 10 } - ) - LP - { lpLine = 12 , lpColumn = 9 , lpStartByte = 289 , lpLength = 15 } - ] - ) - LP - { lpLine = 12 , lpColumn = 1 , lpStartByte = 281 , lpLength = 25 }) - LP - { lpLine = 12 , lpColumn = 1 , lpStartByte = 281 , lpLength = 26 }) - LP - { lpLine = 12 , lpColumn = 1 , lpStartByte = 281 , lpLength = 26 } - , Statement - (Expression - (Call - ( "println" - , [ Binary - ( Equal - LP - { lpLine = 13 , lpColumn = 18 , lpStartByte = 325 , lpLength = 2 } - , Literal - (String - "BYVoid" - LP - { lpLine = 13 , lpColumn = 9 , lpStartByte = 316 , lpLength = 8 }) - LP - { lpLine = 13 , lpColumn = 9 , lpStartByte = 316 , lpLength = 8 } - , Literal - (String - "BYVoid" - LP - { lpLine = 13 , lpColumn = 21 , lpStartByte = 328 , lpLength = 8 }) - LP - { lpLine = 13 , lpColumn = 21 , lpStartByte = 328 , lpLength = 8 } - ) - LP - { lpLine = 13 , lpColumn = 9 , lpStartByte = 316 , lpLength = 20 } - ] - ) - LP - { lpLine = 13 , lpColumn = 1 , lpStartByte = 308 , lpLength = 29 }) - LP - { lpLine = 13 , lpColumn = 1 , lpStartByte = 308 , lpLength = 30 }) - LP - { lpLine = 13 , lpColumn = 1 , lpStartByte = 308 , lpLength = 30 } - ] - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 338 } + { lpLine = 13 , lpColumn = 1 , lpStartByte = 308 , lpLength = 29 } + } + , stmt_annot = + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 308 , lpLength = 30 } + } + , toplevel_annot = + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 308 , lpLength = 30 } + } + ] + , program_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 338 } + } diff --git a/test/testcase/Batsh/while.ast b/test/testcase/Batsh/while.ast index 0aea8b8..a5d9e31 100644 --- a/test/testcase/Batsh/while.ast +++ b/test/testcase/Batsh/while.ast @@ -1,301 +1,795 @@ Program - [ Statement - (Expression - (Assign - ( Identifier - "i" - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } - , Literal - (Int - 0 - LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 }) - LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } - ) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 5 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 }) - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 } - , Statement - (While - ( Binary - ( Less - LP { lpLine = 2 , lpColumn = 10 , lpStartByte = 16 , lpLength = 1 } - , LeftValue - (Identifier - "i" - LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 14 , lpLength = 1 }) - LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 14 , lpLength = 1 } - , Literal - (Int - 5 - LP - { lpLine = 2 , lpColumn = 12 , lpStartByte = 18 , lpLength = 1 }) - LP { lpLine = 2 , lpColumn = 12 , lpStartByte = 18 , lpLength = 1 } - ) - LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 14 , lpLength = 5 } - , Block - [ Expression - (Call - ( "print" - , [ Binary - ( Concat - LP { lpLine = 3 , lpColumn = 11 , lpStartByte = 33 , lpLength = 2 } - , LeftValue - (Identifier - "i" - LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 31 , lpLength = 1 }) - LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 31 , lpLength = 1 } - , Literal - (String - " " - LP - { lpLine = 3 , lpColumn = 14 , lpStartByte = 36 , lpLength = 3 }) - LP { lpLine = 3 , lpColumn = 14 , lpStartByte = 36 , lpLength = 3 } - ) - LP { lpLine = 3 , lpColumn = 9 , lpStartByte = 31 , lpLength = 8 } - ] - ) - LP - { lpLine = 3 , lpColumn = 3 , lpStartByte = 25 , lpLength = 15 }) - LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 25 , lpLength = 16 } - , Expression - (Assign - ( Identifier - "i" - LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 44 , lpLength = 1 } - , Binary - ( Plus - LP { lpLine = 4 , lpColumn = 9 , lpStartByte = 50 , lpLength = 1 } - , LeftValue - (Identifier - "i" - LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 48 , lpLength = 1 }) - LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 48 , lpLength = 1 } - , Literal - (Int - 1 - LP - { lpLine = 4 , lpColumn = 11 , lpStartByte = 52 , lpLength = 1 }) - LP { lpLine = 4 , lpColumn = 11 , lpStartByte = 52 , lpLength = 1 } - ) - LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 48 , lpLength = 5 } - ) - LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 44 , lpLength = 9 }) - LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 44 , lpLength = 10 } - ] - LP - { lpLine = 2 , lpColumn = 15 , lpStartByte = 21 , lpLength = 35 } - ) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 49 }) - LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 49 } - , Statement - (Expression - (Call - ( "println" , [] ) - LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 57 , lpLength = 9 }) - LP - { lpLine = 6 , lpColumn = 1 , lpStartByte = 57 , lpLength = 10 }) - LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 57 , lpLength = 10 } - , Statement - (Comment - " Fibonacci" - LP - { lpLine = 7 , lpColumn = 1 , lpStartByte = 68 , lpLength = 12 }) - LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 68 , lpLength = 12 } - , Statement - (Expression - (Assign - ( Identifier - "n" - LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 1 } - , Literal - (Int - 0 - LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 85 , lpLength = 1 }) - LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 85 , lpLength = 1 } - ) - LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 5 }) - LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 6 }) - LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 6 } - , Statement - (Expression - (Assign - ( Identifier - "i" - LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 1 } - , Literal - (Int - 0 - LP { lpLine = 9 , lpColumn = 5 , lpStartByte = 92 , lpLength = 1 }) - LP { lpLine = 9 , lpColumn = 5 , lpStartByte = 92 , lpLength = 1 } - ) - LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 5 }) - LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 6 }) - LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 6 } - , Statement - (Expression - (Assign - ( Identifier - "j" - LP { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 1 } - , Literal - (Int - 1 - LP - { lpLine = 10 , lpColumn = 5 , lpStartByte = 99 , lpLength = 1 }) - LP { lpLine = 10 , lpColumn = 5 , lpStartByte = 99 , lpLength = 1 } - ) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 5 }) - LP - { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 6 }) - LP { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 6 } - , Statement - (While - ( Binary - ( Less - LP - { lpLine = 11 , lpColumn = 10 , lpStartByte = 111 , lpLength = 1 } - , LeftValue - (Identifier - "n" - LP - { lpLine = 11 , lpColumn = 8 , lpStartByte = 109 , lpLength = 1 }) - LP - { lpLine = 11 , lpColumn = 8 , lpStartByte = 109 , lpLength = 1 } - , Literal - (Int - 40 - LP - { lpLine = 11 , lpColumn = 12 , lpStartByte = 113 , lpLength = 2 }) - LP - { lpLine = 11 , lpColumn = 12 , lpStartByte = 113 , lpLength = 2 } - ) - LP - { lpLine = 11 , lpColumn = 8 , lpStartByte = 109 , lpLength = 6 } - , Block - [ Expression - (Assign - ( Identifier - "k" - LP - { lpLine = 12 , lpColumn = 3 , lpStartByte = 121 , lpLength = 1 } - , Binary - ( Plus - LP - { lpLine = 12 , lpColumn = 9 , lpStartByte = 127 , lpLength = 1 } - , LeftValue - (Identifier - "i" - LP - { lpLine = 12 , lpColumn = 7 , lpStartByte = 125 , lpLength = 1 }) - LP - { lpLine = 12 , lpColumn = 7 , lpStartByte = 125 , lpLength = 1 } - , LeftValue - (Identifier - "j" - LP - { lpLine = 12 , lpColumn = 11 , lpStartByte = 129 , lpLength = 1 }) - LP - { lpLine = 12 , lpColumn = 11 , lpStartByte = 129 , lpLength = 1 } - ) - LP - { lpLine = 12 , lpColumn = 7 , lpStartByte = 125 , lpLength = 5 } - ) - LP - { lpLine = 12 , lpColumn = 3 , lpStartByte = 121 , lpLength = 9 }) - LP - { lpLine = 12 , lpColumn = 3 , lpStartByte = 121 , lpLength = 10 } - , Expression - (Assign - ( Identifier - "i" - LP - { lpLine = 13 , lpColumn = 3 , lpStartByte = 134 , lpLength = 1 } - , LeftValue - (Identifier - "j" - LP - { lpLine = 13 , lpColumn = 7 , lpStartByte = 138 , lpLength = 1 }) - LP - { lpLine = 13 , lpColumn = 7 , lpStartByte = 138 , lpLength = 1 } - ) - LP - { lpLine = 13 , lpColumn = 3 , lpStartByte = 134 , lpLength = 5 }) - LP - { lpLine = 13 , lpColumn = 3 , lpStartByte = 134 , lpLength = 6 } - , Expression - (Assign - ( Identifier - "j" - LP - { lpLine = 14 , lpColumn = 3 , lpStartByte = 143 , lpLength = 1 } - , LeftValue - (Identifier - "k" - LP - { lpLine = 14 , lpColumn = 7 , lpStartByte = 147 , lpLength = 1 }) - LP - { lpLine = 14 , lpColumn = 7 , lpStartByte = 147 , lpLength = 1 } - ) - LP - { lpLine = 14 , lpColumn = 3 , lpStartByte = 143 , lpLength = 5 }) - LP - { lpLine = 14 , lpColumn = 3 , lpStartByte = 143 , lpLength = 6 } - , Expression - (Assign - ( Identifier - "n" - LP - { lpLine = 15 , lpColumn = 3 , lpStartByte = 152 , lpLength = 1 } - , Binary - ( Plus - LP - { lpLine = 15 , lpColumn = 9 , lpStartByte = 158 , lpLength = 1 } - , LeftValue - (Identifier - "n" - LP - { lpLine = 15 , lpColumn = 7 , lpStartByte = 156 , lpLength = 1 }) - LP - { lpLine = 15 , lpColumn = 7 , lpStartByte = 156 , lpLength = 1 } - , Literal - (Int - 1 - LP - { lpLine = 15 , lpColumn = 11 , lpStartByte = 160 , lpLength = 1 }) - LP - { lpLine = 15 , lpColumn = 11 , lpStartByte = 160 , lpLength = 1 } - ) - LP - { lpLine = 15 , lpColumn = 7 , lpStartByte = 156 , lpLength = 5 } - ) - LP - { lpLine = 15 , lpColumn = 3 , lpStartByte = 152 , lpLength = 9 }) - LP - { lpLine = 15 , lpColumn = 3 , lpStartByte = 152 , lpLength = 10 } - , Expression - (Call - ( "println" - , [ LeftValue - (Identifier - "k" - LP - { lpLine = 16 , lpColumn = 11 , lpStartByte = 173 , lpLength = 1 }) + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + LP + { lpLine = 1 + , lpColumn = 5 + , lpStartByte = 4 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } + } + , expr_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 5 } + } + , stmt_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 } + } + , toplevel_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + While + { stmt_expr = + Binary + { expr_binOp = + Less + { binOp_annot = + LP { lpLine = 2 , lpColumn = 10 , lpStartByte = 16 , lpLength = 1 } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + LP + { lpLine = 2 + , lpColumn = 8 + , lpStartByte = 14 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 14 , lpLength = 1 } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 5 + , literal_annot = + LP + { lpLine = 2 + , lpColumn = 12 + , lpStartByte = 18 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 2 , lpColumn = 12 , lpStartByte = 18 , lpLength = 1 } + } + , expr_annot = + LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 14 , lpLength = 5 } + } + , stmt_loop = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "print" + , expr_params = + [ Binary + { expr_binOp = + Concat + { binOp_annot = + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 33 + , lpLength = 2 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 31 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 31 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = " " + , literal_annot = + LP + { lpLine = 3 + , lpColumn = 14 + , lpStartByte = 36 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 3 + , lpColumn = 14 + , lpStartByte = 36 + , lpLength = 3 + } + } + , expr_annot = + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 31 + , lpLength = 8 + } + } + ] + , expr_annot = + LP + { lpLine = 3 + , lpColumn = 3 + , lpStartByte = 25 + , lpLength = 15 + } + } + , stmt_annot = + LP + { lpLine = 3 , lpColumn = 3 , lpStartByte = 25 , lpLength = 16 } + } + , Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + LP + { lpLine = 4 + , lpColumn = 3 + , lpStartByte = 44 + , lpLength = 1 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 50 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + LP + { lpLine = 4 + , lpColumn = 7 + , lpStartByte = 48 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 7 + , lpStartByte = 48 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 4 + , lpColumn = 11 + , lpStartByte = 52 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 11 + , lpStartByte = 52 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 7 + , lpStartByte = 48 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 4 + , lpColumn = 3 + , lpStartByte = 44 + , lpLength = 9 + } + } + , stmt_annot = + LP + { lpLine = 4 , lpColumn = 3 , lpStartByte = 44 , lpLength = 10 } + } + ] + , stmt_annot = + LP + { lpLine = 2 , lpColumn = 15 , lpStartByte = 21 , lpLength = 35 } + } + , stmt_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 49 } + } + , toplevel_annot = + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 49 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = [] + , expr_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 57 , lpLength = 9 } + } + , stmt_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 57 , lpLength = 10 } + } + , toplevel_annot = + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 57 , lpLength = 10 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " Fibonacci" + , stmt_annot = + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 68 , lpLength = 12 } + } + , toplevel_annot = + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 68 , lpLength = 12 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "n" + , lvalue_annot = + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + LP + { lpLine = 8 + , lpColumn = 5 + , lpStartByte = 85 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 85 , lpLength = 1 } + } + , expr_annot = + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 5 } + } + , stmt_annot = + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 6 } + } + , toplevel_annot = + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + LP + { lpLine = 9 + , lpColumn = 5 + , lpStartByte = 92 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 9 , lpColumn = 5 , lpStartByte = 92 , lpLength = 1 } + } + , expr_annot = + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 5 } + } + , stmt_annot = + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 6 } + } + , toplevel_annot = + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "j" + , lvalue_annot = + LP { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 10 + , lpColumn = 5 + , lpStartByte = 99 + , lpLength = 1 + } + } + , expr_annot = + LP { lpLine = 10 , lpColumn = 5 , lpStartByte = 99 , lpLength = 1 } + } + , expr_annot = + LP { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 5 } + } + , stmt_annot = + LP { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 6 } + } + , toplevel_annot = + LP { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + While + { stmt_expr = + Binary + { expr_binOp = + Less + { binOp_annot = + LP + { lpLine = 11 , lpColumn = 10 , lpStartByte = 111 , lpLength = 1 } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "n" + , lvalue_annot = + LP + { lpLine = 11 + , lpColumn = 8 + , lpStartByte = 109 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 11 , lpColumn = 8 , lpStartByte = 109 , lpLength = 1 } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 40 + , literal_annot = + LP + { lpLine = 11 + , lpColumn = 12 + , lpStartByte = 113 + , lpLength = 2 + } + } + , expr_annot = + LP + { lpLine = 11 , lpColumn = 12 , lpStartByte = 113 , lpLength = 2 } + } + , expr_annot = + LP + { lpLine = 11 , lpColumn = 8 , lpStartByte = 109 , lpLength = 6 } + } + , stmt_loop = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "k" + , lvalue_annot = + LP + { lpLine = 12 + , lpColumn = 3 + , lpStartByte = 121 + , lpLength = 1 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 127 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + LP + { lpLine = 12 + , lpColumn = 7 + , lpStartByte = 125 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 7 + , lpStartByte = 125 + , lpLength = 1 + } + } + , expr_right = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "j" + , lvalue_annot = + LP + { lpLine = 12 + , lpColumn = 11 + , lpStartByte = 129 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 11 + , lpStartByte = 129 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 7 + , lpStartByte = 125 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 12 + , lpColumn = 3 + , lpStartByte = 121 + , lpLength = 9 + } + } + , stmt_annot = + LP + { lpLine = 12 + , lpColumn = 3 + , lpStartByte = 121 + , lpLength = 10 + } + } + , Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + LP + { lpLine = 13 + , lpColumn = 3 + , lpStartByte = 134 + , lpLength = 1 + } + } + , expr_subExpr = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "j" + , lvalue_annot = + LP + { lpLine = 13 + , lpColumn = 7 + , lpStartByte = 138 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 13 + , lpColumn = 7 + , lpStartByte = 138 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 13 + , lpColumn = 3 + , lpStartByte = 134 + , lpLength = 5 + } + } + , stmt_annot = + LP + { lpLine = 13 + , lpColumn = 3 + , lpStartByte = 134 + , lpLength = 6 + } + } + , Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "j" + , lvalue_annot = + LP + { lpLine = 14 + , lpColumn = 3 + , lpStartByte = 143 + , lpLength = 1 + } + } + , expr_subExpr = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "k" + , lvalue_annot = + LP + { lpLine = 14 + , lpColumn = 7 + , lpStartByte = 147 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 14 + , lpColumn = 7 + , lpStartByte = 147 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 14 + , lpColumn = 3 + , lpStartByte = 143 + , lpLength = 5 + } + } + , stmt_annot = + LP + { lpLine = 14 + , lpColumn = 3 + , lpStartByte = 143 + , lpLength = 6 + } + } + , Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "n" + , lvalue_annot = + LP + { lpLine = 15 + , lpColumn = 3 + , lpStartByte = 152 + , lpLength = 1 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Plus + { binOp_annot = + LP + { lpLine = 15 + , lpColumn = 9 + , lpStartByte = 158 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "n" + , lvalue_annot = + LP + { lpLine = 15 + , lpColumn = 7 + , lpStartByte = 156 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 15 + , lpColumn = 7 + , lpStartByte = 156 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + LP + { lpLine = 15 + , lpColumn = 11 + , lpStartByte = 160 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 15 + , lpColumn = 11 + , lpStartByte = 160 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 15 + , lpColumn = 7 + , lpStartByte = 156 + , lpLength = 5 + } + } + , expr_annot = + LP + { lpLine = 15 + , lpColumn = 3 + , lpStartByte = 152 + , lpLength = 9 + } + } + , stmt_annot = + LP + { lpLine = 15 + , lpColumn = 3 + , lpStartByte = 152 + , lpLength = 10 + } + } + , Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "k" + , lvalue_annot = + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 173 + , lpLength = 1 + } + } + , expr_annot = + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 173 + , lpLength = 1 + } + } + ] + , expr_annot = + LP + { lpLine = 16 + , lpColumn = 3 + , lpStartByte = 165 + , lpLength = 10 + } + } + , stmt_annot = + LP + { lpLine = 16 + , lpColumn = 3 + , lpStartByte = 165 + , lpLength = 11 + } + } + ] + , stmt_annot = LP - { lpLine = 16 , lpColumn = 11 , lpStartByte = 173 , lpLength = 1 } - ] - ) + { lpLine = 11 , lpColumn = 16 , lpStartByte = 117 , lpLength = 61 } + } + , stmt_annot = LP - { lpLine = 16 , lpColumn = 3 , lpStartByte = 165 , lpLength = 10 }) - LP - { lpLine = 16 , lpColumn = 3 , lpStartByte = 165 , lpLength = 11 } - ] - LP - { lpLine = 11 , lpColumn = 16 , lpStartByte = 117 , lpLength = 61 } - ) - LP - { lpLine = 11 , lpColumn = 1 , lpStartByte = 102 , lpLength = 76 }) - LP - { lpLine = 11 , lpColumn = 1 , lpStartByte = 102 , lpLength = 76 } - ] - LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 178 } + { lpLine = 11 , lpColumn = 1 , lpStartByte = 102 , lpLength = 76 } + } + , toplevel_annot = + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 102 , lpLength = 76 } + } + ] + , program_annot = + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 178 } + } From ae5ca3e91ea4e0f8d184a30123312b64b32d7e9a Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Fri, 7 Nov 2014 20:43:22 +0100 Subject: [PATCH 48/53] TypeCheck w.i.p --- library/Batsh/Ast/Typed.hs | 2 +- library/Batsh/TypeCheck.hs | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/library/Batsh/Ast/Typed.hs b/library/Batsh/Ast/Typed.hs index a1cd6c6..6aa6321 100644 --- a/library/Batsh/Ast/Typed.hs +++ b/library/Batsh/Ast/Typed.hs @@ -3,7 +3,7 @@ module Batsh.Ast.Typed(module Poly, module Batsh.Ast.Typed) where import Batsh.Ast.Poly as Poly import Batsh.Token(LexPos) -data Type = TBool | TInt | TFloat | TString | TList | TNoType +data Type = TBool | TInt | TFloat | TString | TList | TVaribale | TNoType data TypeAnno = TypeAnno Type LexPos diff --git a/library/Batsh/TypeCheck.hs b/library/Batsh/TypeCheck.hs index a292bdb..49fd4cb 100644 --- a/library/Batsh/TypeCheck.hs +++ b/library/Batsh/TypeCheck.hs @@ -17,14 +17,39 @@ instance TypeCheckable PLiteral where String str pos -> String str (TypeAnno TString pos) List exprs pos -> List (typeCheckList exprs) (TypeAnno TList pos) --- All variables are considered as String instance TypeCheckable PLeftValue where typeCheck literal = case literal of - Identifier ident pos -> Identifier ident (TypeAnno TString pos) + Identifier ident pos -> Identifier ident (TypeAnno TVaribale pos) ListAccess lvalue expr pos -> - ListAccess (typeCheck lvalue) (typeCheck expr) (TypeAnno TString pos) + ListAccess (typeCheck lvalue) (typeCheck expr) (TypeAnno TVaribale pos) + +instance TypeCheckable PUnaryOperator where + typeCheck operator = case operator of + Not pos -> Not $ TypeAnno TNoType pos + Negate pos -> Not $ TypeAnno TNoType pos + +instance TypeCheckable PBinaryOperator where + typeCheck operator = case operator of + Plus pos -> Plus $ TypeAnno TNoType pos + Minus pos -> Minus $ TypeAnno TNoType pos + Multiply pos -> Multiply $ TypeAnno TNoType pos + Divide pos -> Divide $ TypeAnno TNoType pos + Modulo pos -> Modulo $ TypeAnno TNoType pos + Concat pos -> Concat $ TypeAnno TNoType pos + Equal pos -> Equal $ TypeAnno TNoType pos + NotEqual pos -> NotEqual $ TypeAnno TNoType pos + ArithEqual pos -> ArithEqual $ TypeAnno TNoType pos + ArithNotEqual pos -> ArithNotEqual $ TypeAnno TNoType pos + Greater pos -> Greater $ TypeAnno TNoType pos + Less pos -> Less $ TypeAnno TNoType pos + GreaterEqual pos -> GreaterEqual $ TypeAnno TNoType pos + LessEqual pos -> LessEqual $ TypeAnno TNoType pos + And pos -> And $ TypeAnno TNoType pos + Or pos -> Or $ TypeAnno TNoType pos instance TypeCheckable PExpression where typeCheck expr = case expr of - LeftValue lvalue pos -> LeftValue (typeCheck lvalue) (TypeAnno TString pos) - Literal literal pos -> Literal (typeCheck literal) (TypeAnno TString pos) + LeftValue lvalue pos -> LeftValue lvalue' (TypeAnno (nodeType lvalue') pos) + where lvalue' = typeCheck lvalue + Literal literal pos -> Literal literal' (TypeAnno (nodeType literal') pos) + where literal' = typeCheck literal From b8577da8e2fde1dc565f2a0bf7d7e3e0fe619704 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Mon, 10 Nov 2014 20:13:28 +0100 Subject: [PATCH 49/53] TypeCheck and unit test --- library/Batsh/Ast.hs | 2 ++ library/Batsh/Ast/Poly.hs | 10 +++++++ library/Batsh/Ast/Typed.hs | 4 +++ library/Batsh/TypeCheck.hs | 60 +++++++++++++++++++++++++++++++++++++- test/TypeCheckTest.hs | 35 ++++++++++++++++++++++ test/UnitTest.hs | 4 ++- 6 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 test/TypeCheckTest.hs diff --git a/library/Batsh/Ast.hs b/library/Batsh/Ast.hs index 4d8b1a6..396c32e 100644 --- a/library/Batsh/Ast.hs +++ b/library/Batsh/Ast.hs @@ -20,3 +20,5 @@ type Statement = PStatement AstAnnotation type TopLevel = PTopLevel AstAnnotation type Program = PProgram AstAnnotation + +type Node = PNode AstAnnotation diff --git a/library/Batsh/Ast/Poly.hs b/library/Batsh/Ast/Poly.hs index 2ef146e..efa98d4 100644 --- a/library/Batsh/Ast/Poly.hs +++ b/library/Batsh/Ast/Poly.hs @@ -135,6 +135,16 @@ data PProgram annot_type } deriving (Eq, Read, Show) +data PNode annot_type + = NodeLiteral (PLiteral annot_type) + | NodeLeftValue (PLeftValue annot_type) + | NodeUnaryOperator (PUnaryOperator annot_type) + | NodeBinaryOperator (PBinaryOperator annot_type) + | NodeExpression (PExpression annot_type) + | NodeStatement (PStatement annot_type) + | NodeTopLevel (PTopLevel annot_type) + | NodeProgram (PProgram annot_type) + type Identifier = String type FunctionName = Identifier diff --git a/library/Batsh/Ast/Typed.hs b/library/Batsh/Ast/Typed.hs index 6aa6321..9cea38c 100644 --- a/library/Batsh/Ast/Typed.hs +++ b/library/Batsh/Ast/Typed.hs @@ -4,8 +4,10 @@ import Batsh.Ast.Poly as Poly import Batsh.Token(LexPos) data Type = TBool | TInt | TFloat | TString | TList | TVaribale | TNoType + deriving (Eq, Read, Show) data TypeAnno = TypeAnno Type LexPos + deriving (Eq, Read, Show) type Literal = PLiteral TypeAnno @@ -23,6 +25,8 @@ type TopLevel = PTopLevel TypeAnno type Program = PProgram TypeAnno +type Node = PNode TypeAnno + nodeType :: AstNode a => a TypeAnno -> Type nodeType node = typ where TypeAnno typ _ = annot node diff --git a/library/Batsh/TypeCheck.hs b/library/Batsh/TypeCheck.hs index 49fd4cb..6197c39 100644 --- a/library/Batsh/TypeCheck.hs +++ b/library/Batsh/TypeCheck.hs @@ -1,14 +1,34 @@ -module Batsh.TypeCheck where +{-#LANGUAGE DeriveDataTypeable#-} +module Batsh.TypeCheck(typeCheck, + TypeCheckError(..)) where import qualified Batsh.Ast as Raw import Batsh.Ast.Typed +import Batsh.Token(LexPos) +import Control.Exception +import Data.Typeable(Typeable) class AstNode a => TypeCheckable a where typeCheck :: a Raw.AstAnnotation -> a TypeAnno +data TypeCheckError + -- expected_type actual_type position + = TypeMismatch [Type] Type LexPos + deriving (Eq, Read, Show, Typeable) + +instance Exception TypeCheckError + typeCheckList :: TypeCheckable a => [a Raw.AstAnnotation] -> [a TypeAnno] typeCheckList list = map typeCheck list +convertType :: AstNode a => [Type] -> (Type -> Type) -> a TypeAnno -> Type +convertType expectedTypes typeConverter node = + if typeOfNode `elem` expectedTypes then + typeConverter typeOfNode + else + throw $ TypeMismatch expectedTypes typeOfNode (nodePos node) + where typeOfNode = nodeType node + instance TypeCheckable PLiteral where typeCheck literal = case literal of Bool bool pos -> Bool bool (TypeAnno TBool pos) @@ -53,3 +73,41 @@ instance TypeCheckable PExpression where where lvalue' = typeCheck lvalue Literal literal pos -> Literal literal' (TypeAnno (nodeType literal') pos) where literal' = typeCheck literal + Unary operator subExpr pos -> checkUnary operator subExpr pos + where + checkUnary :: Raw.UnaryOperator -> Raw.Expression -> Raw.AstAnnotation + -> Expression + checkUnary operator subExpr pos = + Unary operator' subExpr' $ TypeAnno inferredType pos + where + operator' = typeCheck operator + subExpr' = typeCheck subExpr + inferredType = case operator' of + Not _ -> + convertType [TBool, TVaribale] (\_ -> TBool) subExpr' + Negate _ -> + convertType [TInt, TFloat, TVaribale] id subExpr' + checkBinary :: Raw.BinaryOperator -> Raw.Expression -> Raw.Expression + -> Raw.AstAnnotation -> Expression + checkBinary operator left right pos = + Binary operator' left' right' $ TypeAnno inferredType pos + where + operator' = typeCheck operator + left' = typeCheck left + right' = typeCheck right + inferredType = case operator' of + Plus _ -> TInt + +instance TypeCheckable PStatement where + typeCheck stmt = case stmt of + Expression expr pos -> Expression expr' (TypeAnno TNoType pos) + where expr' = typeCheck expr + +instance TypeCheckable PTopLevel where + typeCheck topl = case topl of + Statement stmt pos -> Statement stmt' (TypeAnno TNoType pos) + where stmt' = typeCheck stmt + +instance TypeCheckable PProgram where + typeCheck (Program topls pos) = + Program (typeCheckList topls) (TypeAnno TNoType pos) diff --git a/test/TypeCheckTest.hs b/test/TypeCheckTest.hs new file mode 100644 index 0000000..4c46a9a --- /dev/null +++ b/test/TypeCheckTest.hs @@ -0,0 +1,35 @@ +module TypeCheckTest where + +import Batsh +import Batsh.Ast.Typed +import Batsh.Token(LexPos(..)) +import Batsh.TypeCheck +import Control.Exception +import Prelude hiding(catch) +import Test.HUnit + +testTypeCheck :: Assertion +testTypeCheck = do + assertTypeCheck "3;" $ Program {program_topls = [Statement {toplevel_stmt = + Expression {stmt_expr = Literal {expr_literal = Int {literal_int = 3, + literal_annot = TypeAnno TInt (LP {lpLine = 1, lpColumn = 1, + lpStartByte = 0, lpLength = 1})}, expr_annot = TypeAnno TInt (LP { + lpLine = 1, lpColumn = 1, lpStartByte = 0, lpLength = 1})}, + stmt_annot = TypeAnno TNoType (LP {lpLine = 1, lpColumn = 1, + lpStartByte = 0, lpLength = 2})}, toplevel_annot = TypeAnno TNoType ( + LP {lpLine = 1, lpColumn = 1, lpStartByte = 0, lpLength = 2})}], + program_annot = TypeAnno TNoType (LP {lpLine = 1, lpColumn = 1, + lpStartByte = 0, lpLength = 2})} + catch (print $ typed "!3;") + (handler $ TypeMismatch [TBool,TVaribale] TInt (LP {lpLine = 1, + lpColumn = 2, lpStartByte = 1, lpLength = 1})) + return () + where + typed :: String -> Program + typed code = typeCheck $ parse code + assertTypeCheck :: String -> Program -> Assertion + assertTypeCheck code expected = + let typedAst = typed code in + assertEqual (show typedAst) expected typedAst + handler :: (Eq a, Exception a) => a -> a -> IO () + handler expected ex = assertEqual (show ex) expected ex diff --git a/test/UnitTest.hs b/test/UnitTest.hs index 2f95b4e..72681c7 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -6,6 +6,7 @@ import qualified GeneratorTest import qualified LexerTest import qualified ParserTest import qualified SymbolTableTest +import qualified TypeCheckTest main :: IO () main = defaultMainWithOpts @@ -14,5 +15,6 @@ main = defaultMainWithOpts testCase "ParseFile" ParserTest.testParseFile, testCase "Generator" GeneratorTest.testGenerator, testCase "SymbolTable" SymbolTableTest.testSymbolTable, - testCase "SymbolTableFile" SymbolTableTest.testSymbolTableFile] + testCase "SymbolTableFile" SymbolTableTest.testSymbolTableFile, + testCase "TypeCheck" TypeCheckTest.testTypeCheck] mempty From 069924f655727ef9d253ddc3f784d8ca27a22bf1 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Tue, 11 Nov 2014 20:42:48 +0100 Subject: [PATCH 50/53] TypeCheck cont. --- library/Batsh/Ast/Typed.hs | 2 +- library/Batsh/TypeCheck.hs | 51 ++++++++++++++++++++++++++++++-------- test/TypeCheckTest.hs | 2 +- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/library/Batsh/Ast/Typed.hs b/library/Batsh/Ast/Typed.hs index 9cea38c..6383f3b 100644 --- a/library/Batsh/Ast/Typed.hs +++ b/library/Batsh/Ast/Typed.hs @@ -3,7 +3,7 @@ module Batsh.Ast.Typed(module Poly, module Batsh.Ast.Typed) where import Batsh.Ast.Poly as Poly import Batsh.Token(LexPos) -data Type = TBool | TInt | TFloat | TString | TList | TVaribale | TNoType +data Type = TBool | TInt | TFloat | TString | TList | TVariable | TNoType deriving (Eq, Read, Show) data TypeAnno = TypeAnno Type LexPos diff --git a/library/Batsh/TypeCheck.hs b/library/Batsh/TypeCheck.hs index 6197c39..60523cd 100644 --- a/library/Batsh/TypeCheck.hs +++ b/library/Batsh/TypeCheck.hs @@ -1,5 +1,6 @@ {-#LANGUAGE DeriveDataTypeable#-} module Batsh.TypeCheck(typeCheck, + TypeCheckable, TypeCheckError(..)) where import qualified Batsh.Ast as Raw @@ -14,6 +15,7 @@ class AstNode a => TypeCheckable a where data TypeCheckError -- expected_type actual_type position = TypeMismatch [Type] Type LexPos + | AssignFromNoType LexPos deriving (Eq, Read, Show, Typeable) instance Exception TypeCheckError @@ -39,9 +41,9 @@ instance TypeCheckable PLiteral where instance TypeCheckable PLeftValue where typeCheck literal = case literal of - Identifier ident pos -> Identifier ident (TypeAnno TVaribale pos) + Identifier ident pos -> Identifier ident (TypeAnno TVariable pos) ListAccess lvalue expr pos -> - ListAccess (typeCheck lvalue) (typeCheck expr) (TypeAnno TVaribale pos) + ListAccess (typeCheck lvalue) (typeCheck expr) (TypeAnno TVariable pos) instance TypeCheckable PUnaryOperator where typeCheck operator = case operator of @@ -74,6 +76,10 @@ instance TypeCheckable PExpression where Literal literal pos -> Literal literal' (TypeAnno (nodeType literal') pos) where literal' = typeCheck literal Unary operator subExpr pos -> checkUnary operator subExpr pos + --Binary + Assign lvalue subExpr pos -> checkAssign lvalue subExpr pos + Call func exprs pos -> Call func exprs' (TypeAnno TString pos) -- TODO + where exprs' = typeCheckList exprs where checkUnary :: Raw.UnaryOperator -> Raw.Expression -> Raw.AstAnnotation -> Expression @@ -84,9 +90,9 @@ instance TypeCheckable PExpression where subExpr' = typeCheck subExpr inferredType = case operator' of Not _ -> - convertType [TBool, TVaribale] (\_ -> TBool) subExpr' + convertType [TBool, TVariable] (\_ -> TBool) subExpr' Negate _ -> - convertType [TInt, TFloat, TVaribale] id subExpr' + convertType [TInt, TFloat, TVariable] id subExpr' checkBinary :: Raw.BinaryOperator -> Raw.Expression -> Raw.Expression -> Raw.AstAnnotation -> Expression checkBinary operator left right pos = @@ -95,18 +101,43 @@ instance TypeCheckable PExpression where operator' = typeCheck operator left' = typeCheck left right' = typeCheck right - inferredType = case operator' of - Plus _ -> TInt + inferredType = TVariable -- TODO + checkAssign :: Raw.LeftValue -> Raw.Expression -> Raw.AstAnnotation + -> Expression + checkAssign lvalue subExpr pos = + Assign lvalue' subExpr' $ TypeAnno inferredType pos + where + lvalue' = typeCheck lvalue + subExpr' = typeCheck subExpr + inferredType = case nodeType subExpr' of + TNoType -> throw $ AssignFromNoType (nodePos subExpr') + _ -> nodeType subExpr' instance TypeCheckable PStatement where typeCheck stmt = case stmt of - Expression expr pos -> Expression expr' (TypeAnno TNoType pos) - where expr' = typeCheck expr + Comment comment pos -> Comment comment (TypeAnno TNoType pos) + Block stmts pos -> Block (typeCheckList stmts) (TypeAnno TNoType pos) + Expression expr pos -> Expression (typeCheck expr) (TypeAnno TNoType pos) + If expr thenStmt pos -> + If (typeCheck expr) (typeCheck thenStmt) (TypeAnno TNoType pos) + IfElse expr thenStmt elseStmt pos -> + IfElse (typeCheck expr) (typeCheck thenStmt) + (typeCheck elseStmt) (TypeAnno TNoType pos) + While expr loopStmt pos -> + While (typeCheck expr) (typeCheck loopStmt) (TypeAnno TNoType pos) + Global ident pos -> Global ident (TypeAnno TNoType pos) + Return (Just expr) pos -> + Return (Just $ typeCheck expr) (TypeAnno TNoType pos) + Return Nothing pos -> + Return Nothing (TypeAnno TNoType pos) instance TypeCheckable PTopLevel where typeCheck topl = case topl of - Statement stmt pos -> Statement stmt' (TypeAnno TNoType pos) - where stmt' = typeCheck stmt + Statement stmt pos -> Statement (typeCheck stmt) (TypeAnno TNoType pos) + Function func params stmts pos -> Function func params stmts' annot + where + stmts' = typeCheckList stmts + annot = TypeAnno TNoType pos -- TODO check type of return value instance TypeCheckable PProgram where typeCheck (Program topls pos) = diff --git a/test/TypeCheckTest.hs b/test/TypeCheckTest.hs index 4c46a9a..3d5eccf 100644 --- a/test/TypeCheckTest.hs +++ b/test/TypeCheckTest.hs @@ -21,7 +21,7 @@ testTypeCheck = do program_annot = TypeAnno TNoType (LP {lpLine = 1, lpColumn = 1, lpStartByte = 0, lpLength = 2})} catch (print $ typed "!3;") - (handler $ TypeMismatch [TBool,TVaribale] TInt (LP {lpLine = 1, + (handler $ TypeMismatch [TBool,TVariable] TInt (LP {lpLine = 1, lpColumn = 2, lpStartByte = 1, lpLength = 1})) return () where From b29e75fae5942dd285659fa965078c94ff9f0ddc Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Tue, 11 Nov 2014 20:56:55 +0100 Subject: [PATCH 51/53] Output typed ast with --type --- executable/Main.hs | 10 ++++++++-- library/Batsh.hs | 5 +++++ library/Batsh/TypeCheck.hs | 4 ++-- test/TypeCheckTest.hs | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/executable/Main.hs b/executable/Main.hs index b5985d5..38e12be 100644 --- a/executable/Main.hs +++ b/executable/Main.hs @@ -23,7 +23,8 @@ data Command data BatshOpts = BatshOpts { batshOptsAst :: Bool, batshOptsTokens :: Bool, - batshOptsSymbols :: Bool } + batshOptsSymbols :: Bool, + batshOptsTypeCheck :: Bool } deriving Show version :: Parser (a -> a) @@ -73,10 +74,13 @@ batshOpts = runA $ proc () -> do <> help "Output parsed tokens")) -< () symbols <- asA (switch (long "symbols" <> help "Output symbol table")) -< () + typeCheck <- asA (switch (long "type" + <> help "Output type checked abstract syntax tree")) -< () returnA -< BatshOpts { batshOptsAst = ast, batshOptsTokens = tokens, - batshOptsSymbols = symbols} + batshOptsSymbols = symbols, + batshOptsTypeCheck = typeCheck} bashParser :: Parser Command bashParser = pure Bash @@ -94,6 +98,7 @@ batsh input target opts = do let program = Batsh.parse code let tokens = Batsh.lex code let symbols = Batsh.createSymbolTable program + let typed = Batsh.typeCheck program let outputWithSuffix :: String -> String -> IO (); outputWithSuffix suffix contents = do let fileName = target ++ suffix @@ -101,6 +106,7 @@ batsh input target opts = do when (batshOptsTokens opts) (outputWithSuffix ".tokens" (ppShow tokens)) when (batshOptsAst opts) (outputWithSuffix ".ast" (ppShow program)) when (batshOptsSymbols opts) (outputWithSuffix ".symbols" (ppShow symbols)) + when (batshOptsTypeCheck opts) (outputWithSuffix ".typed" (ppShow typed)) Batsh.generateCodeToFile program target pinfo :: ParserInfo Args diff --git a/library/Batsh.hs b/library/Batsh.hs index 1145ed9..ef28b61 100644 --- a/library/Batsh.hs +++ b/library/Batsh.hs @@ -1,11 +1,13 @@ module Batsh where import qualified Batsh.Ast +import qualified Batsh.Ast.Typed as TypedAst import qualified Batsh.Generator import qualified Batsh.Lexer import qualified Batsh.Parser import qualified Batsh.SymbolTable as SymbolTable import qualified Batsh.Token as Token +import qualified Batsh.TypeCheck as TypeCheck lex :: String -> [Token.Lexeme] lex code = Batsh.Lexer.scanLexemes code @@ -31,3 +33,6 @@ generateCodeToFile = Batsh.Generator.printToFile createSymbolTable :: Batsh.Ast.Program -> SymbolTable.SymbolTable createSymbolTable = SymbolTable.create + +typeCheck :: Batsh.Ast.Program -> TypedAst.Program +typeCheck = TypeCheck.typeCheck diff --git a/library/Batsh/TypeCheck.hs b/library/Batsh/TypeCheck.hs index 60523cd..fc0f58d 100644 --- a/library/Batsh/TypeCheck.hs +++ b/library/Batsh/TypeCheck.hs @@ -48,7 +48,7 @@ instance TypeCheckable PLeftValue where instance TypeCheckable PUnaryOperator where typeCheck operator = case operator of Not pos -> Not $ TypeAnno TNoType pos - Negate pos -> Not $ TypeAnno TNoType pos + Negate pos -> Negate $ TypeAnno TNoType pos instance TypeCheckable PBinaryOperator where typeCheck operator = case operator of @@ -76,7 +76,7 @@ instance TypeCheckable PExpression where Literal literal pos -> Literal literal' (TypeAnno (nodeType literal') pos) where literal' = typeCheck literal Unary operator subExpr pos -> checkUnary operator subExpr pos - --Binary + Binary operator left right pos -> checkBinary operator left right pos Assign lvalue subExpr pos -> checkAssign lvalue subExpr pos Call func exprs pos -> Call func exprs' (TypeAnno TString pos) -- TODO where exprs' = typeCheckList exprs diff --git a/test/TypeCheckTest.hs b/test/TypeCheckTest.hs index 3d5eccf..a8889e5 100644 --- a/test/TypeCheckTest.hs +++ b/test/TypeCheckTest.hs @@ -1,6 +1,6 @@ module TypeCheckTest where -import Batsh +import Batsh(parse) import Batsh.Ast.Typed import Batsh.Token(LexPos(..)) import Batsh.TypeCheck From 60b7b24e6c1e0d195868a3ade7fd834301061428 Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Tue, 11 Nov 2014 21:31:45 +0100 Subject: [PATCH 52/53] TypeCheck done & test files --- library/Batsh/TypeCheck.hs | 61 +- script/update.sh | 2 +- test/testcase/Batsh/arith.typed | 1617 ++++++++++++++++++++++++++ test/testcase/Batsh/array.typed | 1608 +++++++++++++++++++++++++ test/testcase/Batsh/assignment.typed | 685 +++++++++++ test/testcase/Batsh/block.typed | 294 +++++ test/testcase/Batsh/command.typed | 361 ++++++ test/testcase/Batsh/comment.typed | 242 ++++ test/testcase/Batsh/exists.typed | 441 +++++++ test/testcase/Batsh/function.typed | 1332 +++++++++++++++++++++ test/testcase/Batsh/if.typed | 1389 ++++++++++++++++++++++ test/testcase/Batsh/recursion.typed | 1515 ++++++++++++++++++++++++ test/testcase/Batsh/string.typed | 1208 +++++++++++++++++++ test/testcase/Batsh/while.typed | 1013 ++++++++++++++++ 14 files changed, 11756 insertions(+), 12 deletions(-) create mode 100644 test/testcase/Batsh/arith.typed create mode 100644 test/testcase/Batsh/array.typed create mode 100644 test/testcase/Batsh/assignment.typed create mode 100644 test/testcase/Batsh/block.typed create mode 100644 test/testcase/Batsh/command.typed create mode 100644 test/testcase/Batsh/comment.typed create mode 100644 test/testcase/Batsh/exists.typed create mode 100644 test/testcase/Batsh/function.typed create mode 100644 test/testcase/Batsh/if.typed create mode 100644 test/testcase/Batsh/recursion.typed create mode 100644 test/testcase/Batsh/string.typed create mode 100644 test/testcase/Batsh/while.typed diff --git a/library/Batsh/TypeCheck.hs b/library/Batsh/TypeCheck.hs index fc0f58d..b751647 100644 --- a/library/Batsh/TypeCheck.hs +++ b/library/Batsh/TypeCheck.hs @@ -23,14 +23,6 @@ instance Exception TypeCheckError typeCheckList :: TypeCheckable a => [a Raw.AstAnnotation] -> [a TypeAnno] typeCheckList list = map typeCheck list -convertType :: AstNode a => [Type] -> (Type -> Type) -> a TypeAnno -> Type -convertType expectedTypes typeConverter node = - if typeOfNode `elem` expectedTypes then - typeConverter typeOfNode - else - throw $ TypeMismatch expectedTypes typeOfNode (nodePos node) - where typeOfNode = nodeType node - instance TypeCheckable PLiteral where typeCheck literal = case literal of Bool bool pos -> Bool bool (TypeAnno TBool pos) @@ -90,9 +82,9 @@ instance TypeCheckable PExpression where subExpr' = typeCheck subExpr inferredType = case operator' of Not _ -> - convertType [TBool, TVariable] (\_ -> TBool) subExpr' + convertType usableTypes (\_ -> TBool) subExpr' Negate _ -> - convertType [TInt, TFloat, TVariable] id subExpr' + convertType usableTypes id subExpr' checkBinary :: Raw.BinaryOperator -> Raw.Expression -> Raw.Expression -> Raw.AstAnnotation -> Expression checkBinary operator left right pos = @@ -101,7 +93,23 @@ instance TypeCheckable PExpression where operator' = typeCheck operator left' = typeCheck left right' = typeCheck right - inferredType = TVariable -- TODO + inferredType = case operator' of + Plus _ -> convertType2 usableTypes numTypeEscalate left' right' + Minus _ -> convertType2 usableTypes numTypeEscalate left' right' + Multiply _ -> convertType2 usableTypes numTypeEscalate left' right' + Divide _ -> convertType2 usableTypes numTypeEscalate left' right' + Modulo _ -> convertType2 usableTypes numTypeEscalate left' right' + Concat _ -> convertType2 usableTypes (\_ _ -> TString) left' right' + Equal _ -> convertType2 usableTypes toBool left' right' + NotEqual _ -> convertType2 usableTypes toBool left' right' + ArithEqual _ -> convertType2 usableTypes toBool left' right' + ArithNotEqual _ -> convertType2 usableTypes toBool left' right' + Greater _ -> convertType2 usableTypes toBool left' right' + Less _ -> convertType2 usableTypes toBool left' right' + GreaterEqual _ -> convertType2 usableTypes toBool left' right' + LessEqual _ -> convertType2 usableTypes toBool left' right' + And _ -> convertType2 usableTypes toBool left' right' + Or _ -> convertType2 usableTypes toBool left' right' checkAssign :: Raw.LeftValue -> Raw.Expression -> Raw.AstAnnotation -> Expression checkAssign lvalue subExpr pos = @@ -112,6 +120,37 @@ instance TypeCheckable PExpression where inferredType = case nodeType subExpr' of TNoType -> throw $ AssignFromNoType (nodePos subExpr') _ -> nodeType subExpr' + convertType :: AstNode a => [Type] -> (Type -> Type) -> a TypeAnno -> Type + convertType expectedTypes typeConverter node = + if typeOfNode `elem` expectedTypes then + typeConverter typeOfNode + else + throw $ TypeMismatch expectedTypes typeOfNode (nodePos node) + where typeOfNode = nodeType node + convertType2 :: AstNode a => [Type] -> (Type -> Type -> Type) + -> a TypeAnno -> a TypeAnno -> Type + convertType2 expectedTypes typeConverter left right = + convertType expectedTypes (\leftType -> + convertType expectedTypes (\rightType -> + typeConverter leftType rightType + ) right + ) left + numTypeEscalate :: Type -> Type -> Type + numTypeEscalate left right = case (left, right) of + (TInt, TInt) -> TInt + (TInt, TFloat) -> TFloat + (TFloat, TInt) -> TFloat + (TFloat, TFloat) -> TFloat + (TVariable, TInt) -> TInt + (TInt, TVariable) -> TInt + (TVariable, TFloat) -> TFloat + (TFloat, TVariable) -> TFloat + (TVariable, TVariable) -> TVariable + _ -> TVariable + toBool :: Type -> Type -> Type + toBool _ _ = TBool + stringTypes = [TString, TVariable] + usableTypes = [TBool, TInt, TFloat, TString, TVariable] instance TypeCheckable PStatement where typeCheck stmt = case stmt of diff --git a/script/update.sh b/script/update.sh index 93643cf..729d685 100755 --- a/script/update.sh +++ b/script/update.sh @@ -5,7 +5,7 @@ for filename in ${inputDir}/*.batsh; do echo $caseName input=${inputDir}/${caseName}.batsh output=${inputDir}/${caseName} - ./batsh batsh $input $output --ast --symbols + ./batsh batsh $input $output --ast --symbols --type diff $input $output if [ "$?" == $((0)) ]; then rm $output diff --git a/test/testcase/Batsh/arith.typed b/test/testcase/Batsh/arith.typed new file mode 100644 index 0000000..568849e --- /dev/null +++ b/test/testcase/Batsh/arith.typed @@ -0,0 +1,1617 @@ +Program + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + Bool + { literal_bool = False + , literal_annot = + TypeAnno + TBool + LP + { lpLine = 1 + , lpColumn = 9 + , lpStartByte = 8 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 5 } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 14 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + Bool + { literal_bool = True + , literal_annot = + TypeAnno + TBool + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 24 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 24 + , lpLength = 4 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 13 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 14 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 14 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + Int + { literal_int = 42 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 39 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 39 + , lpLength = 2 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 31 , lpLength = 11 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 31 , lpLength = 12 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 31 , lpLength = 12 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 4 + , lpColumn = 11 + , lpStartByte = 54 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 52 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 52 + , lpLength = 1 + } + } + , expr_right = + Binary + { expr_binOp = + Multiply + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 4 + , lpColumn = 21 + , lpStartByte = 64 + , lpLength = 1 + } + } + , expr_left = + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 4 + , lpColumn = 16 + , lpStartByte = 59 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 14 + , lpStartByte = 57 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 14 + , lpStartByte = 57 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 6 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 18 + , lpStartByte = 61 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 18 + , lpStartByte = 61 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 14 + , lpStartByte = 57 + , lpLength = 5 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 23 + , lpStartByte = 66 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 23 + , lpStartByte = 66 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 14 + , lpStartByte = 57 + , lpLength = 10 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 52 + , lpLength = 15 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 44 , lpLength = 24 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 44 , lpLength = 25 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 44 , lpLength = 25 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Minus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 80 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 8 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 78 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 78 + , lpLength = 1 + } + } + , expr_right = + Binary + { expr_binOp = + Modulo + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 5 + , lpColumn = 15 + , lpStartByte = 84 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 13 + , lpStartByte = 82 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 13 + , lpStartByte = 82 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 17 + , lpStartByte = 86 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 17 + , lpStartByte = 86 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 13 + , lpStartByte = 82 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 78 + , lpLength = 9 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 18 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 19 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 19 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Minus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 6 + , lpColumn = 12 + , lpStartByte = 101 + , lpLength = 1 + } + } + , expr_left = + Unary + { expr_unOp = + Negate + { unOp_annot = + TypeAnno + TNoType + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 98 + , lpLength = 1 + } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 9 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 10 + , lpStartByte = 99 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 10 + , lpStartByte = 99 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 98 + , lpLength = 2 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 9 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 14 + , lpStartByte = 103 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 14 + , lpStartByte = 103 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 98 + , lpLength = 6 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 90 , lpLength = 15 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 90 , lpLength = 16 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 90 , lpLength = 16 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Divide + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 7 + , lpColumn = 17 + , lpStartByte = 123 + , lpLength = 1 + } + } + , expr_left = + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 7 + , lpColumn = 12 + , lpStartByte = 118 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 116 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 116 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 8 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 14 + , lpStartByte = 120 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 14 + , lpStartByte = 120 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 116 + , lpLength = 5 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 19 + , lpStartByte = 125 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 19 + , lpStartByte = 125 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 116 + , lpLength = 10 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 107 , lpLength = 20 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 107 , lpLength = 21 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 107 , lpLength = 21 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + ArithEqual + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 8 + , lpColumn = 11 + , lpStartByte = 139 + , lpLength = 3 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 137 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 137 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 15 + , lpStartByte = 143 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 15 + , lpStartByte = 143 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 137 + , lpLength = 7 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 129 , lpLength = 16 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 129 , lpLength = 17 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 129 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + ArithNotEqual + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 9 + , lpColumn = 11 + , lpStartByte = 157 + , lpLength = 3 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 6 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 155 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 155 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 8 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 15 + , lpStartByte = 161 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 15 + , lpStartByte = 161 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 155 + , lpLength = 7 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 147 , lpLength = 16 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 147 , lpLength = 17 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 147 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Greater + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 10 + , lpColumn = 11 + , lpStartByte = 175 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 173 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 173 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 10 + , lpColumn = 13 + , lpStartByte = 177 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 10 + , lpColumn = 13 + , lpStartByte = 177 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 173 + , lpLength = 5 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 165 , lpLength = 14 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 165 , lpLength = 15 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 165 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Less + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 11 + , lpColumn = 11 + , lpStartByte = 191 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 189 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 189 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 5 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 11 + , lpColumn = 13 + , lpStartByte = 193 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 11 + , lpColumn = 13 + , lpStartByte = 193 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 189 + , lpLength = 5 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 181 , lpLength = 14 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 181 , lpLength = 15 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 181 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + GreaterEqual + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 12 + , lpColumn = 11 + , lpStartByte = 207 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 6 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 205 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 205 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 12 + , lpColumn = 14 + , lpStartByte = 210 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 12 + , lpColumn = 14 + , lpStartByte = 210 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 205 + , lpLength = 6 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 197 , lpLength = 15 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 197 , lpLength = 16 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 197 , lpLength = 16 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + LessEqual + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 13 + , lpColumn = 12 + , lpStartByte = 225 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 19 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 222 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 222 + , lpLength = 2 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 30 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 13 + , lpColumn = 15 + , lpStartByte = 228 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 13 + , lpColumn = 15 + , lpStartByte = 228 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 222 + , lpLength = 8 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 214 , lpLength = 17 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 214 , lpLength = 18 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 214 , lpLength = 18 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Unary + { expr_unOp = + Not + { unOp_annot = + TypeAnno + TNoType + LP + { lpLine = 14 + , lpColumn = 9 + , lpStartByte = 241 + , lpLength = 1 + } + } + , expr_subExpr = + Literal + { expr_literal = + Bool + { literal_bool = True + , literal_annot = + TypeAnno + TBool + LP + { lpLine = 14 + , lpColumn = 10 + , lpStartByte = 242 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 14 + , lpColumn = 10 + , lpStartByte = 242 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 14 + , lpColumn = 9 + , lpStartByte = 241 + , lpLength = 5 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 233 , lpLength = 14 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 233 , lpLength = 15 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 233 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Unary + { expr_unOp = + Not + { unOp_annot = + TypeAnno + TNoType + LP + { lpLine = 15 + , lpColumn = 9 + , lpStartByte = 257 + , lpLength = 1 + } + } + , expr_subExpr = + Literal + { expr_literal = + Bool + { literal_bool = False + , literal_annot = + TypeAnno + TBool + LP + { lpLine = 15 + , lpColumn = 10 + , lpStartByte = 258 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 15 + , lpColumn = 10 + , lpStartByte = 258 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 15 + , lpColumn = 9 + , lpStartByte = 257 + , lpLength = 6 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 249 , lpLength = 15 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 249 , lpLength = 16 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 249 , lpLength = 16 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Unary + { expr_unOp = + Not + { unOp_annot = + TypeAnno + TNoType + LP + { lpLine = 16 + , lpColumn = 9 + , lpStartByte = 274 + , lpLength = 1 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Minus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 16 + , lpColumn = 13 + , lpStartByte = 278 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 276 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 276 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 16 + , lpColumn = 15 + , lpStartByte = 280 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 16 + , lpColumn = 15 + , lpStartByte = 280 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 276 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 16 + , lpColumn = 9 + , lpStartByte = 274 + , lpLength = 7 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 266 , lpLength = 17 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 266 , lpLength = 18 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 266 , lpLength = 18 } + } + ] + , program_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 284 } + } diff --git a/test/testcase/Batsh/array.typed b/test/testcase/Batsh/array.typed new file mode 100644 index 0000000..5b0e410 --- /dev/null +++ b/test/testcase/Batsh/array.typed @@ -0,0 +1,1608 @@ +Program + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + List + { literal_list = + [ Literal + { expr_literal = + String + { literal_str = "" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 1 + , lpColumn = 6 + , lpStartByte = 5 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 1 + , lpColumn = 6 + , lpStartByte = 5 + , lpLength = 2 + } + } + , Literal + { expr_literal = + String + { literal_str = "y" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 1 + , lpColumn = 10 + , lpStartByte = 9 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 1 + , lpColumn = 10 + , lpStartByte = 9 + , lpLength = 3 + } + } + , Unary + { expr_unOp = + Negate + { unOp_annot = + TypeAnno + TNoType + LP + { lpLine = 1 + , lpColumn = 15 + , lpStartByte = 14 + , lpLength = 1 + } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 16 + , lpStartByte = 15 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 16 + , lpStartByte = 15 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 15 + , lpStartByte = 14 + , lpLength = 2 + } + } + , Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 19 + , lpStartByte = 18 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 19 + , lpStartByte = 18 + , lpLength = 1 + } + } + ] + , literal_annot = + TypeAnno + TList + LP + { lpLine = 1 + , lpColumn = 5 + , lpStartByte = 4 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TList + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } + } + , expr_annot = + TypeAnno + TList + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 5 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 21 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 21 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 2 + , lpColumn = 1 + , lpStartByte = 22 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 2 + , lpColumn = 3 + , lpStartByte = 24 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 2 + , lpColumn = 3 + , lpStartByte = 24 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 4 } + } + , expr_subExpr = + Binary + { expr_binOp = + Multiply + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 2 + , lpColumn = 10 + , lpStartByte = 31 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 2 + , lpColumn = 8 + , lpStartByte = 29 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 2 + , lpColumn = 8 + , lpStartByte = 29 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 9 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 2 + , lpColumn = 12 + , lpStartByte = 33 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 2 + , lpColumn = 12 + , lpStartByte = 33 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 29 , lpLength = 5 } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 12 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 13 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 22 , lpLength = 13 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 1 + , lpStartByte = 36 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 3 + , lpColumn = 3 + , lpStartByte = 38 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 3 + , lpColumn = 3 + , lpStartByte = 38 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 4 } + } + , expr_subExpr = + Literal + { expr_literal = + String + { literal_str = "abx" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 3 + , lpColumn = 8 + , lpStartByte = 43 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TString + LP { lpLine = 3 , lpColumn = 8 , lpStartByte = 43 , lpLength = 5 } + } + , expr_annot = + TypeAnno + TString + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 12 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 13 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 36 , lpLength = 13 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 4 + , lpColumn = 1 + , lpStartByte = 50 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 3 + , lpStartByte = 52 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 3 + , lpStartByte = 52 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 4 } + } + , expr_subExpr = + Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 4 + , lpColumn = 12 + , lpStartByte = 61 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "5" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 4 + , lpColumn = 8 + , lpStartByte = 57 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 4 + , lpColumn = 8 + , lpStartByte = 57 + , lpLength = 3 + } + } + , expr_right = + LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 4 + , lpColumn = 15 + , lpStartByte = 64 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 17 + , lpStartByte = 66 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 17 + , lpStartByte = 66 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 4 + , lpColumn = 15 + , lpStartByte = 64 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 4 + , lpColumn = 15 + , lpStartByte = 64 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 4 , lpColumn = 8 , lpStartByte = 57 , lpLength = 11 } + } + , expr_annot = + TypeAnno + TString + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 18 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 19 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 50 , lpLength = 19 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 78 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 80 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 80 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 78 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 78 + , lpLength = 4 + } + } + , LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 15 + , lpStartByte = 84 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 17 + , lpStartByte = 86 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 17 + , lpStartByte = 86 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 15 + , lpStartByte = 84 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 15 + , lpStartByte = 84 + , lpLength = 4 + } + } + , LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 21 + , lpStartByte = 90 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 23 + , lpStartByte = 92 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 23 + , lpStartByte = 92 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 21 + , lpStartByte = 90 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 21 + , lpStartByte = 90 + , lpLength = 4 + } + } + , LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 27 + , lpStartByte = 96 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 29 + , lpStartByte = 98 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 29 + , lpStartByte = 98 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 27 + , lpStartByte = 96 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 27 + , lpStartByte = 96 + , lpLength = 4 + } + } + , LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 33 + , lpStartByte = 102 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 35 + , lpStartByte = 104 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 35 + , lpStartByte = 104 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 33 + , lpStartByte = 102 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 33 + , lpStartByte = 102 + , lpLength = 4 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 37 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 38 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 70 , lpLength = 38 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + List + { literal_list = + [ Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 6 + , lpStartByte = 114 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 6 + , lpStartByte = 114 + , lpLength = 1 + } + } + , Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 117 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 117 + , lpLength = 1 + } + } + , Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 12 + , lpStartByte = 120 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 12 + , lpStartByte = 120 + , lpLength = 1 + } + } + ] + , literal_annot = + TypeAnno + TList + LP + { lpLine = 6 + , lpColumn = 5 + , lpStartByte = 113 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TList + LP + { lpLine = 6 , lpColumn = 5 , lpStartByte = 113 , lpLength = 1 } + } + , expr_annot = + TypeAnno + TList + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 5 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 14 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 109 , lpLength = 14 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 9 + , lpStartByte = 132 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 11 + , lpStartByte = 134 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 11 + , lpStartByte = 134 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 9 + , lpStartByte = 132 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 9 + , lpStartByte = 132 + , lpLength = 4 + } + } + , LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 15 + , lpStartByte = 138 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 17 + , lpStartByte = 140 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 17 + , lpStartByte = 140 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 15 + , lpStartByte = 138 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 15 + , lpStartByte = 138 + , lpLength = 4 + } + } + , LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 21 + , lpStartByte = 144 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 23 + , lpStartByte = 146 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 7 + , lpColumn = 23 + , lpStartByte = 146 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 21 + , lpStartByte = 144 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 21 + , lpStartByte = 144 + , lpLength = 4 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 124 , lpLength = 25 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 124 , lpLength = 26 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 124 , lpLength = 26 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Multiply + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 8 + , lpColumn = 24 + , lpStartByte = 174 + , lpLength = 1 + } + } + , expr_left = + Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 8 + , lpColumn = 15 + , lpStartByte = 165 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "10" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 10 + , lpStartByte = 160 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 10 + , lpStartByte = 160 + , lpLength = 4 + } + } + , expr_right = + LeftValue + { expr_lvalue = + ListAccess + { lvalue_var = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 8 + , lpColumn = 18 + , lpStartByte = 168 + , lpLength = 1 + } + } + , lvalue_index = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 20 + , lpStartByte = 170 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 20 + , lpStartByte = 170 + , lpLength = 1 + } + } + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 8 + , lpColumn = 18 + , lpStartByte = 168 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 8 + , lpColumn = 18 + , lpStartByte = 168 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 10 + , lpStartByte = 160 + , lpLength = 12 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 26 + , lpStartByte = 176 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 26 + , lpStartByte = 176 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 8 + , lpColumn = 10 + , lpStartByte = 160 + , lpLength = 17 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 151 , lpLength = 27 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 151 , lpLength = 28 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 151 , lpLength = 28 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Call + { expr_func = "len" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 9 + , lpColumn = 13 + , lpStartByte = 192 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 9 + , lpColumn = 13 + , lpStartByte = 192 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 188 + , lpLength = 6 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 180 , lpLength = 15 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 180 , lpLength = 16 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 180 , lpLength = 16 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Multiply + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 10 + , lpColumn = 16 + , lpStartByte = 212 + , lpLength = 1 + } + } + , expr_left = + Call + { expr_func = "len" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 10 + , lpColumn = 13 + , lpStartByte = 209 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 10 + , lpColumn = 13 + , lpStartByte = 209 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 205 + , lpLength = 6 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 8 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 10 + , lpColumn = 18 + , lpStartByte = 214 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 10 + , lpColumn = 18 + , lpStartByte = 214 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 205 + , lpLength = 10 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 197 , lpLength = 19 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 197 , lpLength = 20 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 197 , lpLength = 20 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = "println([1, 2, 3]);" + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 218 , lpLength = 21 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 218 , lpLength = 21 } + } + ] + , program_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 239 } + } diff --git a/test/testcase/Batsh/assignment.typed b/test/testcase/Batsh/assignment.typed new file mode 100644 index 0000000..71acac8 --- /dev/null +++ b/test/testcase/Batsh/assignment.typed @@ -0,0 +1,685 @@ +Program + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } + } + , expr_subExpr = + Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 1 + , lpColumn = 15 + , lpStartByte = 14 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "Value: " + , literal_annot = + TypeAnno + TString + LP + { lpLine = 1 + , lpColumn = 5 + , lpStartByte = 4 + , lpLength = 9 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 1 + , lpColumn = 5 + , lpStartByte = 4 + , lpLength = 9 + } + } + , expr_right = + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 1 + , lpColumn = 20 + , lpStartByte = 19 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 18 + , lpStartByte = 17 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 18 + , lpStartByte = 17 + , lpLength = 1 + } + } + , expr_right = + Binary + { expr_binOp = + Multiply + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 1 + , lpColumn = 30 + , lpStartByte = 29 + , lpLength = 1 + } + } + , expr_left = + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 1 + , lpColumn = 25 + , lpStartByte = 24 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 23 + , lpStartByte = 22 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 23 + , lpStartByte = 22 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 6 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 27 + , lpStartByte = 26 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 27 + , lpStartByte = 26 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 23 + , lpStartByte = 22 + , lpLength = 5 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 32 + , lpStartByte = 31 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 32 + , lpStartByte = 31 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 23 + , lpStartByte = 22 + , lpLength = 10 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 18 + , lpStartByte = 17 + , lpLength = 15 + } + } + , expr_annot = + TypeAnno + TString + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 28 } + } + , expr_annot = + TypeAnno + TString + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 32 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 42 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 42 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 34 , lpLength = 10 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 34 , lpLength = 11 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 34 , lpLength = 11 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "b" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 1 } + } + , expr_subExpr = + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 3 + , lpColumn = 7 + , lpStartByte = 52 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 3 + , lpColumn = 5 + , lpStartByte = 50 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 3 + , lpColumn = 5 + , lpStartByte = 50 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 54 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 54 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 50 , lpLength = 5 } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 9 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 10 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 46 , lpLength = 10 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "b" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 65 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 65 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 57 , lpLength = 10 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 57 , lpLength = 11 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 57 , lpLength = 11 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "c" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 1 } + } + , expr_subExpr = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 5 + , lpStartByte = 73 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP { lpLine = 5 , lpColumn = 5 , lpStartByte = 73 , lpLength = 1 } + } + , expr_annot = + TypeAnno + TVariable + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 5 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 6 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 69 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "c" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 84 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 84 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 76 , lpLength = 10 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 76 , lpLength = 11 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 76 , lpLength = 11 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "d" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 1 } + } + , expr_subExpr = + Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 7 + , lpColumn = 7 + , lpStartByte = 94 + , lpLength = 2 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "b" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 5 + , lpStartByte = 92 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 5 + , lpStartByte = 92 + , lpLength = 1 + } + } + , expr_right = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "c" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 97 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 97 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TString + LP { lpLine = 7 , lpColumn = 5 , lpStartByte = 92 , lpLength = 6 } + } + , expr_annot = + TypeAnno + TString + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 10 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 11 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 88 , lpLength = 11 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "d" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 108 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 108 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 100 , lpLength = 10 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 100 , lpLength = 11 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 100 , lpLength = 11 } + } + ] + , program_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 111 } + } diff --git a/test/testcase/Batsh/block.typed b/test/testcase/Batsh/block.typed new file mode 100644 index 0000000..3efc619 --- /dev/null +++ b/test/testcase/Batsh/block.typed @@ -0,0 +1,294 @@ +Program + { program_topls = + [ Statement + { toplevel_stmt = + Comment + { stmt_comment = "Level 0 Start" + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Hello" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 24 + , lpLength = 7 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 24 + , lpLength = 7 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 16 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 17 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 16 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Block + { stmt_stmts = + [ Comment + { stmt_comment = "Level 1 Start" + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 38 , lpLength = 15 } + } + , Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Lo" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 64 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 64 + , lpLength = 4 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 3 + , lpStartByte = 56 + , lpLength = 13 + } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 3 , lpStartByte = 56 , lpLength = 14 } + } + , Block + { stmt_stmts = + [ Comment + { stmt_comment = "Level 2 Start" + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 7 + , lpColumn = 5 + , lpStartByte = 79 + , lpLength = 15 + } + } + , Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "and behold" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 13 + , lpStartByte = 107 + , lpLength = 12 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 13 + , lpStartByte = 107 + , lpLength = 12 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 5 + , lpStartByte = 99 + , lpLength = 21 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 8 + , lpColumn = 5 + , lpStartByte = 99 + , lpLength = 22 + } + } + , Comment + { stmt_comment = "Level 2 End" + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 9 + , lpColumn = 5 + , lpStartByte = 126 + , lpLength = 13 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 6 , lpColumn = 3 , lpStartByte = 73 , lpLength = 70 } + } + , Comment + { stmt_comment = "Level 1 End" + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 3 , lpStartByte = 146 , lpLength = 13 } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 34 , lpLength = 127 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 3 , lpColumn = 1 , lpStartByte = 34 , lpLength = 127 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "End" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 170 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 170 + , lpLength = 5 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 162 , lpLength = 14 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 162 , lpLength = 15 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 162 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = "Level 0 End" + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 178 , lpLength = 13 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 178 , lpLength = 13 } + } + ] + , program_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 191 } + } diff --git a/test/testcase/Batsh/command.typed b/test/testcase/Batsh/command.typed new file mode 100644 index 0000000..2cf008e --- /dev/null +++ b/test/testcase/Batsh/command.typed @@ -0,0 +1,361 @@ +Program + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "call" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "println" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 1 + , lpColumn = 6 + , lpStartByte = 5 + , lpLength = 9 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 9 } + } + , Literal + { expr_literal = + String + { literal_str = "Println Called" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 1 + , lpColumn = 17 + , lpStartByte = 16 + , lpLength = 16 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 1 + , lpColumn = 17 + , lpStartByte = 16 + , lpLength = 16 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 34 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 34 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "cmd" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 3 } + } + , expr_subExpr = + Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 2 + , lpColumn = 12 + , lpStartByte = 46 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "ec" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 2 + , lpColumn = 7 + , lpStartByte = 41 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 2 + , lpColumn = 7 + , lpStartByte = 41 + , lpLength = 4 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "ho" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 2 + , lpColumn = 15 + , lpStartByte = 49 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 2 + , lpColumn = 15 + , lpStartByte = 49 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 2 , lpColumn = 7 , lpStartByte = 41 , lpLength = 12 } + } + , expr_annot = + TypeAnno + TString + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 18 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 19 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 35 , lpLength = 19 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "call" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "cmd" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 6 + , lpStartByte = 60 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 6 + , lpStartByte = 60 + , lpLength = 3 + } + } + , Literal + { expr_literal = + String + { literal_str = "Echo Called" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 65 + , lpLength = 13 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 65 + , lpLength = 13 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 55 , lpLength = 24 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 55 , lpLength = 25 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 55 , lpLength = 25 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "retval" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 6 } + } + , expr_subExpr = + Call + { expr_func = "echo" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Value 100%" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 4 + , lpColumn = 15 + , lpStartByte = 95 + , lpLength = 12 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 4 + , lpColumn = 15 + , lpStartByte = 95 + , lpLength = 12 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 4 + , lpColumn = 10 + , lpStartByte = 90 + , lpLength = 18 + } + } + , expr_annot = + TypeAnno + TString + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 27 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 28 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 81 , lpLength = 28 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "retval" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 118 + , lpLength = 6 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 118 + , lpLength = 6 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 110 , lpLength = 15 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 110 , lpLength = 16 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 5 , lpColumn = 1 , lpStartByte = 110 , lpLength = 16 } + } + ] + , program_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 126 } + } diff --git a/test/testcase/Batsh/comment.typed b/test/testcase/Batsh/comment.typed new file mode 100644 index 0000000..795bf36 --- /dev/null +++ b/test/testcase/Batsh/comment.typed @@ -0,0 +1,242 @@ +Program + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 5 + , lpStartByte = 4 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 5 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " This is comment 1" + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 20 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 20 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 1 } + } + , expr_subExpr = + Binary + { expr_binOp = + Multiply + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 3 + , lpColumn = 7 + , lpStartByte = 34 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 5 + , lpStartByte = 32 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 5 + , lpStartByte = 32 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 5 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 36 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 36 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 3 , lpColumn = 5 , lpStartByte = 32 , lpLength = 5 } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 9 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 10 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 28 , lpLength = 10 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " This is comment 2" + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 39 , lpLength = 20 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 39 , lpLength = 20 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "a" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 68 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 68 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 60 , lpLength = 10 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 60 , lpLength = 11 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 60 , lpLength = 11 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = "This is comment 3" + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 72 , lpLength = 19 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 72 , lpLength = 19 } + } + ] + , program_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 91 } + } diff --git a/test/testcase/Batsh/exists.typed b/test/testcase/Batsh/exists.typed new file mode 100644 index 0000000..1a4a362 --- /dev/null +++ b/test/testcase/Batsh/exists.typed @@ -0,0 +1,441 @@ +Program + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "ex" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 2 } + } + , expr_subExpr = + Call + { expr_func = "exists" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Makefile" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 1 + , lpColumn = 13 + , lpStartByte = 12 + , lpLength = 10 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 1 + , lpColumn = 13 + , lpStartByte = 12 + , lpLength = 10 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 1 , lpColumn = 6 , lpStartByte = 5 , lpLength = 18 } + } + , expr_annot = + TypeAnno + TString + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 23 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 24 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 24 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "ex" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 33 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 33 + , lpLength = 2 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 25 , lpLength = 11 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 25 , lpLength = 12 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 25 , lpLength = 12 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "exists" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Makefile" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 3 + , lpColumn = 8 + , lpStartByte = 45 + , lpLength = 10 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 3 + , lpColumn = 8 + , lpStartByte = 45 + , lpLength = 10 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 18 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 19 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 19 } + } + , Statement + { toplevel_stmt = + If + { stmt_expr = + Call + { expr_func = "exists" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Makefile" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 4 + , lpColumn = 12 + , lpStartByte = 69 + , lpLength = 10 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 4 + , lpColumn = 12 + , lpStartByte = 69 + , lpLength = 10 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 4 , lpColumn = 5 , lpStartByte = 62 , lpLength = 18 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Yes" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 94 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 11 + , lpStartByte = 94 + , lpLength = 5 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 3 + , lpStartByte = 86 + , lpLength = 14 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 5 + , lpColumn = 3 + , lpStartByte = 86 + , lpLength = 15 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 4 , lpColumn = 25 , lpStartByte = 82 , lpLength = 21 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 58 , lpLength = 45 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 58 , lpLength = 45 } + } + , Statement + { toplevel_stmt = + IfElse + { stmt_expr = + Call + { expr_func = "exists" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "none" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 7 + , lpColumn = 12 + , lpStartByte = 115 + , lpLength = 6 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 7 + , lpColumn = 12 + , lpStartByte = 115 + , lpLength = 6 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 7 , lpColumn = 5 , lpStartByte = 108 , lpLength = 14 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Impossible" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 11 + , lpStartByte = 136 + , lpLength = 12 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 11 + , lpStartByte = 136 + , lpLength = 12 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 3 + , lpStartByte = 128 + , lpLength = 21 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 8 + , lpColumn = 3 + , lpStartByte = 128 + , lpLength = 22 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 7 , lpColumn = 21 , lpStartByte = 124 , lpLength = 28 } + } + , stmt_else = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "No" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 10 + , lpColumn = 11 + , lpStartByte = 170 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 10 + , lpColumn = 11 + , lpStartByte = 170 + , lpLength = 4 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 10 + , lpColumn = 3 + , lpStartByte = 162 + , lpLength = 13 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 10 + , lpColumn = 3 + , lpStartByte = 162 + , lpLength = 14 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 9 , lpColumn = 8 , lpStartByte = 158 , lpLength = 20 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 104 , lpLength = 74 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 104 , lpLength = 74 } + } + ] + , program_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 178 } + } diff --git a/test/testcase/Batsh/function.typed b/test/testcase/Batsh/function.typed new file mode 100644 index 0000000..b16cbe6 --- /dev/null +++ b/test/testcase/Batsh/function.typed @@ -0,0 +1,1332 @@ +Program + { program_topls = + [ Statement + { toplevel_stmt = + Comment + { stmt_comment = " Function call" + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 16 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 16 } + } + , Function + { toplevel_func = "func1" + , toplevel_params = [ "p1" , "p2" ] + , toplevel_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "p1" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 52 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 52 + , lpLength = 2 + } + } + , LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "p2" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 15 + , lpStartByte = 56 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 15 + , lpStartByte = 56 + , lpLength = 2 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 44 , lpLength = 15 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 44 , lpLength = 16 } + } + ] + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 17 , lpLength = 45 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "func1" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Hello" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 7 + , lpStartByte = 69 + , lpLength = 7 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 7 + , lpStartByte = 69 + , lpLength = 7 + } + } + , Literal + { expr_literal = + String + { literal_str = "World" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 16 + , lpStartByte = 78 + , lpLength = 7 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 16 + , lpStartByte = 78 + , lpLength = 7 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 63 , lpLength = 23 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 63 , lpLength = 24 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 63 , lpLength = 24 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " Global and local variables" + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 88 , lpLength = 29 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 88 , lpLength = 29 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v1" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 2 } + } + , expr_subExpr = + Literal + { expr_literal = + String + { literal_str = "Global V1" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 7 + , lpColumn = 6 + , lpStartByte = 123 + , lpLength = 11 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 7 + , lpColumn = 6 + , lpStartByte = 123 + , lpLength = 11 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 16 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 17 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 118 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v2" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 2 } + } + , expr_subExpr = + Literal + { expr_literal = + String + { literal_str = "Global V2" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 6 + , lpStartByte = 141 + , lpLength = 11 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 6 + , lpStartByte = 141 + , lpLength = 11 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 16 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 17 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 136 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v3" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 2 } + } + , expr_subExpr = + Literal + { expr_literal = + String + { literal_str = "Global V3" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 9 + , lpColumn = 6 + , lpStartByte = 159 + , lpLength = 11 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 9 + , lpColumn = 6 + , lpStartByte = 159 + , lpLength = 11 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 16 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 17 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 154 , lpLength = 17 } + } + , Function + { toplevel_func = "func2" + , toplevel_params = [ "p" ] + , toplevel_stmts = + [ Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v1" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 11 + , lpColumn = 3 + , lpStartByte = 194 + , lpLength = 2 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 11 + , lpColumn = 17 + , lpStartByte = 208 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "Local " + , literal_annot = + TypeAnno + TString + LP + { lpLine = 11 + , lpColumn = 8 + , lpStartByte = 199 + , lpLength = 8 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 11 + , lpColumn = 8 + , lpStartByte = 199 + , lpLength = 8 + } + } + , expr_right = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "p" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 11 + , lpColumn = 20 + , lpStartByte = 211 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 11 + , lpColumn = 20 + , lpStartByte = 211 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 11 + , lpColumn = 8 + , lpStartByte = 199 + , lpLength = 13 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 11 , lpColumn = 3 , lpStartByte = 194 , lpLength = 18 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 3 , lpStartByte = 194 , lpLength = 19 } + } + , Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "v1" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 12 + , lpColumn = 11 + , lpStartByte = 224 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 12 + , lpColumn = 11 + , lpStartByte = 224 + , lpLength = 2 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 12 , lpColumn = 3 , lpStartByte = 216 , lpLength = 11 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 12 , lpColumn = 3 , lpStartByte = 216 , lpLength = 12 } + } + , Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "v2" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 13 + , lpColumn = 11 + , lpStartByte = 239 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 13 + , lpColumn = 11 + , lpStartByte = 239 + , lpLength = 2 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 13 , lpColumn = 3 , lpStartByte = 231 , lpLength = 11 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 13 , lpColumn = 3 , lpStartByte = 231 , lpLength = 12 } + } + , Global + { stmt_ident = "v3" + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 14 , lpColumn = 3 , lpStartByte = 246 , lpLength = 10 } + } + , Global + { stmt_ident = "v4" + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 15 , lpColumn = 3 , lpStartByte = 259 , lpLength = 10 } + } + , Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v3" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 16 + , lpColumn = 3 + , lpStartByte = 272 + , lpLength = 2 + } + } + , expr_subExpr = + Literal + { expr_literal = + String + { literal_str = "V3 Modified." + , literal_annot = + TypeAnno + TString + LP + { lpLine = 16 + , lpColumn = 8 + , lpStartByte = 277 + , lpLength = 14 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 16 + , lpColumn = 8 + , lpStartByte = 277 + , lpLength = 14 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 16 , lpColumn = 3 , lpStartByte = 272 , lpLength = 19 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 16 , lpColumn = 3 , lpStartByte = 272 , lpLength = 20 } + } + ] + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 172 , lpLength = 122 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "func2" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Var" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 18 + , lpColumn = 7 + , lpStartByte = 301 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 18 + , lpColumn = 7 + , lpStartByte = 301 + , lpLength = 5 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 295 , lpLength = 12 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 295 , lpLength = 13 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 295 , lpLength = 13 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "v1" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 19 + , lpColumn = 9 + , lpStartByte = 317 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 19 + , lpColumn = 9 + , lpStartByte = 317 + , lpLength = 2 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 309 , lpLength = 11 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 309 , lpLength = 12 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 309 , lpLength = 12 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "v3" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 20 + , lpColumn = 9 + , lpStartByte = 330 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 20 + , lpColumn = 9 + , lpStartByte = 330 + , lpLength = 2 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 20 , lpColumn = 1 , lpStartByte = 322 , lpLength = 11 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 20 , lpColumn = 1 , lpStartByte = 322 , lpLength = 12 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 20 , lpColumn = 1 , lpStartByte = 322 , lpLength = 12 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " Return value" + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 21 , lpColumn = 1 , lpStartByte = 335 , lpLength = 15 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 21 , lpColumn = 1 , lpStartByte = 335 , lpLength = 15 } + } + , Function + { toplevel_func = "func3" + , toplevel_params = [ "num" ] + , toplevel_stmts = + [ Return + { stmt_retval = + Just + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 23 + , lpColumn = 14 + , lpStartByte = 386 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 23 + , lpColumn = 10 + , lpStartByte = 382 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 23 + , lpColumn = 10 + , lpStartByte = 382 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 41 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 23 + , lpColumn = 16 + , lpStartByte = 388 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 23 + , lpColumn = 16 + , lpStartByte = 388 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 23 , lpColumn = 10 , lpStartByte = 382 , lpLength = 8 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 23 , lpColumn = 3 , lpStartByte = 375 , lpLength = 16 } + } + ] + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 22 , lpColumn = 1 , lpStartByte = 351 , lpLength = 42 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "func3" + , expr_params = + [ Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 25 + , lpColumn = 7 + , lpStartByte = 400 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 25 + , lpColumn = 7 + , lpStartByte = 400 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 394 , lpLength = 8 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 394 , lpLength = 9 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 394 , lpLength = 9 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = [] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 26 , lpColumn = 1 , lpStartByte = 404 , lpLength = 9 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 26 , lpColumn = 1 , lpStartByte = 404 , lpLength = 10 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 26 , lpColumn = 1 , lpStartByte = 404 , lpLength = 10 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "ret" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 27 + , lpColumn = 1 + , lpStartByte = 415 + , lpLength = 3 + } + } + , expr_subExpr = + Call + { expr_func = "func3" + , expr_params = + [ Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 27 + , lpColumn = 13 + , lpStartByte = 427 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 27 + , lpColumn = 13 + , lpStartByte = 427 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 27 + , lpColumn = 7 + , lpStartByte = 421 + , lpLength = 8 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 14 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 15 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 27 , lpColumn = 1 , lpStartByte = 415 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Returned:" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 28 + , lpColumn = 9 + , lpStartByte = 439 + , lpLength = 11 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 28 + , lpColumn = 9 + , lpStartByte = 439 + , lpLength = 11 + } + } + , LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "ret" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 28 + , lpColumn = 22 + , lpStartByte = 452 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 28 + , lpColumn = 22 + , lpStartByte = 452 + , lpLength = 3 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 431 , lpLength = 25 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 431 , lpLength = 26 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 431 , lpLength = 26 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " Argument containing space" + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 29 , lpColumn = 1 , lpStartByte = 458 , lpLength = 28 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 29 , lpColumn = 1 , lpStartByte = 458 , lpLength = 28 } + } + , Function + { toplevel_func = "g" + , toplevel_params = [ "text" ] + , toplevel_stmts = + [ Return + { stmt_retval = + Just + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "text" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 31 + , lpColumn = 10 + , lpStartByte = 515 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 31 , lpColumn = 10 , lpStartByte = 515 , lpLength = 4 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 31 , lpColumn = 3 , lpStartByte = 508 , lpLength = 12 } + } + ] + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 30 , lpColumn = 1 , lpStartByte = 487 , lpLength = 35 } + } + , Function + { toplevel_func = "f" + , toplevel_params = [ "text" ] + , toplevel_stmts = + [ Return + { stmt_retval = + Just + Call + { expr_func = "g" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "text" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 34 + , lpColumn = 12 + , lpStartByte = 553 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 34 + , lpColumn = 12 + , lpStartByte = 553 + , lpLength = 4 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 34 , lpColumn = 10 , lpStartByte = 551 , lpLength = 7 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 34 , lpColumn = 3 , lpStartByte = 544 , lpLength = 15 } + } + ] + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 33 , lpColumn = 1 , lpStartByte = 523 , lpLength = 38 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "test" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 36 + , lpColumn = 1 + , lpStartByte = 562 + , lpLength = 4 + } + } + , expr_subExpr = + Call + { expr_func = "f" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Param with space" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 36 + , lpColumn = 10 + , lpStartByte = 571 + , lpLength = 18 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 36 + , lpColumn = 10 + , lpStartByte = 571 + , lpLength = 18 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 36 + , lpColumn = 8 + , lpStartByte = 569 + , lpLength = 21 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 28 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 29 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 36 , lpColumn = 1 , lpStartByte = 562 , lpLength = 29 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "test" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 37 + , lpColumn = 9 + , lpStartByte = 600 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 37 + , lpColumn = 9 + , lpStartByte = 600 + , lpLength = 4 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 37 , lpColumn = 1 , lpStartByte = 592 , lpLength = 13 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 37 , lpColumn = 1 , lpStartByte = 592 , lpLength = 14 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 37 , lpColumn = 1 , lpStartByte = 592 , lpLength = 14 } + } + ] + , program_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 606 } + } diff --git a/test/testcase/Batsh/if.typed b/test/testcase/Batsh/if.typed new file mode 100644 index 0000000..ee0318e --- /dev/null +++ b/test/testcase/Batsh/if.typed @@ -0,0 +1,1389 @@ +Program + { program_topls = + [ Statement + { toplevel_stmt = + If + { stmt_expr = + Binary + { expr_binOp = + Less + { binOp_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 7 , lpStartByte = 6 , lpLength = 1 } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 5 + , lpStartByte = 4 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 10 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 9 + , lpStartByte = 8 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 2 } + } + , expr_annot = + TypeAnno + TBool + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 6 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Yes" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 2 + , lpColumn = 11 + , lpStartByte = 24 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 2 + , lpColumn = 11 + , lpStartByte = 24 + , lpLength = 5 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 2 + , lpColumn = 3 + , lpStartByte = 16 + , lpLength = 14 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 2 + , lpColumn = 3 + , lpStartByte = 16 + , lpLength = 15 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 1 , lpColumn = 13 , lpStartByte = 12 , lpLength = 21 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 33 } + } + , Statement + { toplevel_stmt = + IfElse + { stmt_expr = + Literal + { expr_literal = + Bool + { literal_bool = True + , literal_annot = + TypeAnno + TBool + LP { lpLine = 4 , lpColumn = 5 , lpStartByte = 38 , lpLength = 4 } + } + , expr_annot = + TypeAnno + TBool + LP { lpLine = 4 , lpColumn = 5 , lpStartByte = 38 , lpLength = 4 } + } + , stmt_then = + Block + { stmt_stmts = + [ IfElse + { stmt_expr = + Literal + { expr_literal = + Bool + { literal_bool = False + , literal_annot = + TypeAnno + TBool + LP + { lpLine = 5 + , lpColumn = 7 + , lpStartByte = 52 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 5 + , lpColumn = 7 + , lpStartByte = 52 + , lpLength = 5 + } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 6 + , lpColumn = 5 + , lpStartByte = 65 + , lpLength = 1 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 6 + , lpColumn = 11 + , lpStartByte = 71 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 4 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 69 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 69 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 13 + , lpStartByte = 73 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 13 + , lpStartByte = 73 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 9 + , lpStartByte = 69 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 6 + , lpColumn = 5 + , lpStartByte = 65 + , lpLength = 9 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 6 + , lpColumn = 5 + , lpStartByte = 65 + , lpLength = 10 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 5 + , lpColumn = 14 + , lpStartByte = 59 + , lpLength = 20 + } + } + , stmt_else = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "v" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 8 + , lpColumn = 5 + , lpStartByte = 91 + , lpLength = 1 + } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 95 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 95 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 5 + , lpStartByte = 91 + , lpLength = 5 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 8 + , lpColumn = 5 + , lpStartByte = 91 + , lpLength = 6 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 7 + , lpColumn = 10 + , lpStartByte = 85 + , lpLength = 16 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 5 + , lpColumn = 3 + , lpStartByte = 48 + , lpLength = 53 + } + } + , If + { stmt_expr = + Literal + { expr_literal = + Bool + { literal_bool = False + , literal_annot = + TypeAnno + TBool + LP + { lpLine = 10 + , lpColumn = 7 + , lpStartByte = 108 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 10 + , lpColumn = 7 + , lpStartByte = 108 + , lpLength = 5 + } + } + , stmt_then = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "no" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 10 + , lpColumn = 22 + , lpStartByte = 123 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 10 + , lpColumn = 22 + , lpStartByte = 123 + , lpLength = 4 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 10 + , lpColumn = 14 + , lpStartByte = 115 + , lpLength = 13 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 10 + , lpColumn = 14 + , lpStartByte = 115 + , lpLength = 14 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 10 + , lpColumn = 3 + , lpStartByte = 104 + , lpLength = 25 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 4 , lpColumn = 11 , lpStartByte = 44 , lpLength = 87 } + } + , stmt_else = + Block + { stmt_stmts = [] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 8 , lpStartByte = 137 , lpLength = 4 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 34 , lpLength = 107 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 4 , lpColumn = 1 , lpStartByte = 34 , lpLength = 107 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "v" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 14 + , lpColumn = 9 + , lpStartByte = 150 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 14 + , lpColumn = 9 + , lpStartByte = 150 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 142 , lpLength = 10 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 142 , lpLength = 11 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 14 , lpColumn = 1 , lpStartByte = 142 , lpLength = 11 } + } + , Statement + { toplevel_stmt = + If + { stmt_expr = + Binary + { expr_binOp = + Greater + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 15 + , lpColumn = 7 + , lpStartByte = 160 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 15 + , lpColumn = 5 + , lpStartByte = 158 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 15 + , lpColumn = 5 + , lpStartByte = 158 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 15 + , lpColumn = 9 + , lpStartByte = 162 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 15 + , lpColumn = 9 + , lpStartByte = 162 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 15 , lpColumn = 5 , lpStartByte = 158 , lpLength = 5 } + } + , stmt_then = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "True" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 15 + , lpColumn = 20 + , lpStartByte = 173 + , lpLength = 6 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 15 + , lpColumn = 20 + , lpStartByte = 173 + , lpLength = 6 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 15 + , lpColumn = 12 + , lpStartByte = 165 + , lpLength = 15 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 15 , lpColumn = 12 , lpStartByte = 165 , lpLength = 16 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 154 , lpLength = 27 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 15 , lpColumn = 1 , lpStartByte = 154 , lpLength = 27 } + } + , Statement + { toplevel_stmt = + If + { stmt_expr = + Binary + { expr_binOp = + ArithEqual + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 16 + , lpColumn = 7 + , lpStartByte = 188 + , lpLength = 3 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 16 + , lpColumn = 5 + , lpStartByte = 186 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 16 + , lpColumn = 5 + , lpStartByte = 186 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 12 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 192 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 192 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 16 , lpColumn = 5 , lpStartByte = 186 , lpLength = 8 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "No" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 17 + , lpColumn = 11 + , lpStartByte = 208 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 17 + , lpColumn = 11 + , lpStartByte = 208 + , lpLength = 4 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 17 + , lpColumn = 3 + , lpStartByte = 200 + , lpLength = 13 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 17 + , lpColumn = 3 + , lpStartByte = 200 + , lpLength = 14 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 16 , lpColumn = 15 , lpStartByte = 196 , lpLength = 20 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 182 , lpLength = 34 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 16 , lpColumn = 1 , lpStartByte = 182 , lpLength = 34 } + } + , Statement + { toplevel_stmt = + IfElse + { stmt_expr = + Binary + { expr_binOp = + Equal + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 19 + , lpColumn = 9 + , lpStartByte = 225 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "a" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 19 + , lpColumn = 5 + , lpStartByte = 221 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 19 + , lpColumn = 5 + , lpStartByte = 221 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "b" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 19 + , lpColumn = 12 + , lpStartByte = 228 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 19 + , lpColumn = 12 + , lpStartByte = 228 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 19 , lpColumn = 5 , lpStartByte = 221 , lpLength = 10 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "No" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 20 + , lpColumn = 11 + , lpStartByte = 245 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 20 + , lpColumn = 11 + , lpStartByte = 245 + , lpLength = 4 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 20 + , lpColumn = 3 + , lpStartByte = 237 + , lpLength = 13 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 20 + , lpColumn = 3 + , lpStartByte = 237 + , lpLength = 14 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 19 , lpColumn = 17 , lpStartByte = 233 , lpLength = 20 } + } + , stmt_else = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "a is not b" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 22 + , lpColumn = 11 + , lpStartByte = 271 + , lpLength = 12 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 22 + , lpColumn = 11 + , lpStartByte = 271 + , lpLength = 12 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 22 + , lpColumn = 3 + , lpStartByte = 263 + , lpLength = 21 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 22 + , lpColumn = 3 + , lpStartByte = 263 + , lpLength = 22 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 21 , lpColumn = 8 , lpStartByte = 259 , lpLength = 28 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 217 , lpLength = 70 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 217 , lpLength = 70 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 24 + , lpColumn = 1 + , lpStartByte = 288 + , lpLength = 3 + } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 43 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 24 + , lpColumn = 7 + , lpStartByte = 294 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 24 + , lpColumn = 7 + , lpStartByte = 294 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 8 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 9 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 24 , lpColumn = 1 , lpStartByte = 288 , lpLength = 9 } + } + , Statement + { toplevel_stmt = + If + { stmt_expr = + Binary + { expr_binOp = + Equal + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 25 + , lpColumn = 10 + , lpStartByte = 307 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "43" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 25 + , lpColumn = 5 + , lpStartByte = 302 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 25 + , lpColumn = 5 + , lpStartByte = 302 + , lpLength = 4 + } + } + , expr_right = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 25 + , lpColumn = 13 + , lpStartByte = 310 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 25 + , lpColumn = 13 + , lpStartByte = 310 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 25 , lpColumn = 5 , lpStartByte = 302 , lpLength = 11 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "43 == num" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 26 + , lpColumn = 11 + , lpStartByte = 327 + , lpLength = 11 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 26 + , lpColumn = 11 + , lpStartByte = 327 + , lpLength = 11 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 26 + , lpColumn = 3 + , lpStartByte = 319 + , lpLength = 20 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 26 + , lpColumn = 3 + , lpStartByte = 319 + , lpLength = 21 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 25 , lpColumn = 18 , lpStartByte = 315 , lpLength = 27 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 298 , lpLength = 44 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 25 , lpColumn = 1 , lpStartByte = 298 , lpLength = 44 } + } + , Statement + { toplevel_stmt = + If + { stmt_expr = + Binary + { expr_binOp = + ArithEqual + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 28 + , lpColumn = 10 + , lpStartByte = 352 + , lpLength = 3 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "43" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 28 + , lpColumn = 5 + , lpStartByte = 347 + , lpLength = 4 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 28 + , lpColumn = 5 + , lpStartByte = 347 + , lpLength = 4 + } + } + , expr_right = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 28 + , lpColumn = 14 + , lpStartByte = 356 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 28 + , lpColumn = 14 + , lpStartByte = 356 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 28 , lpColumn = 5 , lpStartByte = 347 , lpLength = 12 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "43 === num" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 29 + , lpColumn = 11 + , lpStartByte = 373 + , lpLength = 12 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 29 + , lpColumn = 11 + , lpStartByte = 373 + , lpLength = 12 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 29 + , lpColumn = 3 + , lpStartByte = 365 + , lpLength = 21 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 29 + , lpColumn = 3 + , lpStartByte = 365 + , lpLength = 22 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 28 , lpColumn = 19 , lpStartByte = 361 , lpLength = 28 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 343 , lpLength = 46 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 343 , lpLength = 46 } + } + ] + , program_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 389 } + } diff --git a/test/testcase/Batsh/recursion.typed b/test/testcase/Batsh/recursion.typed new file mode 100644 index 0000000..f175a24 --- /dev/null +++ b/test/testcase/Batsh/recursion.typed @@ -0,0 +1,1515 @@ +Program + { program_topls = + [ Statement + { toplevel_stmt = + Comment + { stmt_comment = " Loop" + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 7 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 7 } + } + , Function + { toplevel_func = "loop" + , toplevel_params = [ "num" ] + , toplevel_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 39 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 39 + , lpLength = 3 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 31 , lpLength = 12 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 3 , lpStartByte = 31 , lpLength = 13 } + } + , If + { stmt_expr = + Binary + { expr_binOp = + Greater + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 4 + , lpColumn = 11 + , lpStartByte = 55 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 4 + , lpColumn = 7 + , lpStartByte = 51 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 4 + , lpColumn = 7 + , lpStartByte = 51 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 13 + , lpStartByte = 57 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 13 + , lpStartByte = 57 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TBool + LP { lpLine = 4 , lpColumn = 7 , lpStartByte = 51 , lpLength = 7 } + } + , stmt_then = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "loop" + , expr_params = + [ Binary + { expr_binOp = + Minus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 5 + , lpColumn = 14 + , lpStartByte = 75 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 10 + , lpStartByte = 71 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 5 + , lpColumn = 10 + , lpStartByte = 71 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 16 + , lpStartByte = 77 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 16 + , lpStartByte = 77 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 5 + , lpColumn = 10 + , lpStartByte = 71 + , lpLength = 7 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 5 + , lpStartByte = 66 + , lpLength = 13 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 5 + , lpColumn = 5 + , lpStartByte = 66 + , lpLength = 14 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 4 , lpColumn = 16 , lpStartByte = 60 , lpLength = 24 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 3 , lpStartByte = 47 , lpLength = 37 } + } + ] + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 8 , lpLength = 78 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "loop" + , expr_params = + [ Literal + { expr_literal = + Int + { literal_int = 10 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 6 + , lpStartByte = 92 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 6 + , lpStartByte = 92 + , lpLength = 2 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 87 , lpLength = 8 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 87 , lpLength = 9 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 87 , lpLength = 9 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " Factorial" + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 97 , lpLength = 12 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 97 , lpLength = 12 } + } + , Function + { toplevel_func = "fact" + , toplevel_params = [ "num" ] + , toplevel_stmts = + [ IfElse + { stmt_expr = + Binary + { expr_binOp = + ArithEqual + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 11 + , lpColumn = 11 + , lpStartByte = 141 + , lpLength = 3 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 11 + , lpColumn = 7 + , lpStartByte = 137 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 11 + , lpColumn = 7 + , lpStartByte = 137 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 11 + , lpColumn = 15 + , lpStartByte = 145 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 11 + , lpColumn = 15 + , lpStartByte = 145 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 11 , lpColumn = 7 , lpStartByte = 137 , lpLength = 9 } + } + , stmt_then = + Block + { stmt_stmts = + [ Return + { stmt_retval = + Just + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 12 + , lpColumn = 12 + , lpStartByte = 161 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 12 + , lpColumn = 12 + , lpStartByte = 161 + , lpLength = 1 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 12 + , lpColumn = 5 + , lpStartByte = 154 + , lpLength = 9 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 18 , lpStartByte = 148 , lpLength = 19 } + } + , stmt_else = + Block + { stmt_stmts = + [ Return + { stmt_retval = + Just + Binary + { expr_binOp = + Multiply + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 14 + , lpColumn = 26 + , lpStartByte = 200 + , lpLength = 1 + } + } + , expr_left = + Call + { expr_func = "fact" + , expr_params = + [ Binary + { expr_binOp = + Minus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 14 + , lpColumn = 21 + , lpStartByte = 195 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 14 + , lpColumn = 17 + , lpStartByte = 191 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 14 + , lpColumn = 17 + , lpStartByte = 191 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 14 + , lpColumn = 23 + , lpStartByte = 197 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 14 + , lpColumn = 23 + , lpStartByte = 197 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 14 + , lpColumn = 17 + , lpStartByte = 191 + , lpLength = 7 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 14 + , lpColumn = 12 + , lpStartByte = 186 + , lpLength = 13 + } + } + , expr_right = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 14 + , lpColumn = 28 + , lpStartByte = 202 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 14 + , lpColumn = 28 + , lpStartByte = 202 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 14 + , lpColumn = 12 + , lpStartByte = 186 + , lpLength = 19 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 14 + , lpColumn = 5 + , lpStartByte = 179 + , lpLength = 27 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 13 , lpColumn = 10 , lpStartByte = 173 , lpLength = 37 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 3 , lpStartByte = 133 , lpLength = 77 } + } + ] + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 110 , lpLength = 102 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Call + { expr_func = "fact" + , expr_params = + [ Literal + { expr_literal = + Int + { literal_int = 5 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 17 + , lpColumn = 14 + , lpStartByte = 226 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 17 + , lpColumn = 14 + , lpStartByte = 226 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 17 + , lpColumn = 9 + , lpStartByte = 221 + , lpLength = 7 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 17 , lpColumn = 1 , lpStartByte = 213 , lpLength = 16 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 17 , lpColumn = 1 , lpStartByte = 213 , lpLength = 17 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 17 , lpColumn = 1 , lpStartByte = 213 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " Fibonacci" + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 231 , lpLength = 12 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 18 , lpColumn = 1 , lpStartByte = 231 , lpLength = 12 } + } + , Function + { toplevel_func = "fibonacci" + , toplevel_params = [ "num" ] + , toplevel_stmts = + [ IfElse + { stmt_expr = + Binary + { expr_binOp = + ArithEqual + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 20 + , lpColumn = 11 + , lpStartByte = 280 + , lpLength = 3 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 20 + , lpColumn = 7 + , lpStartByte = 276 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 20 + , lpColumn = 7 + , lpStartByte = 276 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 20 + , lpColumn = 15 + , lpStartByte = 284 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 20 + , lpColumn = 15 + , lpStartByte = 284 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 20 , lpColumn = 7 , lpStartByte = 276 , lpLength = 9 } + } + , stmt_then = + Block + { stmt_stmts = + [ Return + { stmt_retval = + Just + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 21 + , lpColumn = 12 + , lpStartByte = 300 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 21 + , lpColumn = 12 + , lpStartByte = 300 + , lpLength = 1 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 21 + , lpColumn = 5 + , lpStartByte = 293 + , lpLength = 9 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 20 , lpColumn = 18 , lpStartByte = 287 , lpLength = 19 } + } + , stmt_else = + IfElse + { stmt_expr = + Binary + { expr_binOp = + ArithEqual + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 22 + , lpColumn = 18 + , lpStartByte = 320 + , lpLength = 3 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 22 + , lpColumn = 14 + , lpStartByte = 316 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 22 + , lpColumn = 14 + , lpStartByte = 316 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 22 + , lpColumn = 22 + , lpStartByte = 324 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 22 + , lpColumn = 22 + , lpStartByte = 324 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 22 + , lpColumn = 14 + , lpStartByte = 316 + , lpLength = 9 + } + } + , stmt_then = + Block + { stmt_stmts = + [ Return + { stmt_retval = + Just + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 23 + , lpColumn = 12 + , lpStartByte = 340 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 23 + , lpColumn = 12 + , lpStartByte = 340 + , lpLength = 1 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 23 + , lpColumn = 5 + , lpStartByte = 333 + , lpLength = 9 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 22 + , lpColumn = 25 + , lpStartByte = 327 + , lpLength = 19 + } + } + , stmt_else = + Block + { stmt_stmts = + [ Return + { stmt_retval = + Just + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 25 + , lpColumn = 31 + , lpStartByte = 384 + , lpLength = 1 + } + } + , expr_left = + Call + { expr_func = "fibonacci" + , expr_params = + [ Binary + { expr_binOp = + Minus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 25 + , lpColumn = 26 + , lpStartByte = 379 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 25 + , lpColumn = 22 + , lpStartByte = 375 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 25 + , lpColumn = 22 + , lpStartByte = 375 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 25 + , lpColumn = 28 + , lpStartByte = 381 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 25 + , lpColumn = 28 + , lpStartByte = 381 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 25 + , lpColumn = 22 + , lpStartByte = 375 + , lpLength = 7 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 25 + , lpColumn = 12 + , lpStartByte = 365 + , lpLength = 18 + } + } + , expr_right = + Call + { expr_func = "fibonacci" + , expr_params = + [ Binary + { expr_binOp = + Minus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 25 + , lpColumn = 47 + , lpStartByte = 400 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "num" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 25 + , lpColumn = 43 + , lpStartByte = 396 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 25 + , lpColumn = 43 + , lpStartByte = 396 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 25 + , lpColumn = 49 + , lpStartByte = 402 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 25 + , lpColumn = 49 + , lpStartByte = 402 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 25 + , lpColumn = 43 + , lpStartByte = 396 + , lpLength = 7 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 25 + , lpColumn = 33 + , lpStartByte = 386 + , lpLength = 18 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 25 + , lpColumn = 12 + , lpStartByte = 365 + , lpLength = 39 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 25 + , lpColumn = 5 + , lpStartByte = 358 + , lpLength = 47 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 24 + , lpColumn = 10 + , lpStartByte = 352 + , lpLength = 57 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 22 , lpColumn = 10 , lpStartByte = 312 , lpLength = 97 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 20 , lpColumn = 3 , lpStartByte = 272 , lpLength = 137 } + } + ] + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 19 , lpColumn = 1 , lpStartByte = 244 , lpLength = 167 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 28 + , lpColumn = 1 + , lpStartByte = 412 + , lpLength = 1 + } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 28 + , lpColumn = 5 + , lpStartByte = 416 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 28 + , lpColumn = 5 + , lpStartByte = 416 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 5 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 6 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 28 , lpColumn = 1 , lpStartByte = 412 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + While + { stmt_expr = + Binary + { expr_binOp = + Less + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 29 + , lpColumn = 10 + , lpStartByte = 428 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 29 + , lpColumn = 8 + , lpStartByte = 426 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 29 + , lpColumn = 8 + , lpStartByte = 426 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 7 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 29 + , lpColumn = 12 + , lpStartByte = 430 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 29 + , lpColumn = 12 + , lpStartByte = 430 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 29 , lpColumn = 8 , lpStartByte = 426 , lpLength = 5 } + } + , stmt_loop = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Call + { expr_func = "fibonacci" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 30 + , lpColumn = 21 + , lpStartByte = 455 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 30 + , lpColumn = 21 + , lpStartByte = 455 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 30 + , lpColumn = 11 + , lpStartByte = 445 + , lpLength = 12 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 30 + , lpColumn = 3 + , lpStartByte = 437 + , lpLength = 21 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 30 + , lpColumn = 3 + , lpStartByte = 437 + , lpLength = 22 + } + } + , Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 31 + , lpColumn = 3 + , lpStartByte = 462 + , lpLength = 1 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 31 + , lpColumn = 9 + , lpStartByte = 468 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 31 + , lpColumn = 7 + , lpStartByte = 466 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 31 + , lpColumn = 7 + , lpStartByte = 466 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 31 + , lpColumn = 11 + , lpStartByte = 470 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 31 + , lpColumn = 11 + , lpStartByte = 470 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 31 + , lpColumn = 7 + , lpStartByte = 466 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 31 + , lpColumn = 3 + , lpStartByte = 462 + , lpLength = 9 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 31 + , lpColumn = 3 + , lpStartByte = 462 + , lpLength = 10 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 29 , lpColumn = 15 , lpStartByte = 433 , lpLength = 41 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 29 , lpColumn = 1 , lpStartByte = 419 , lpLength = 55 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 29 , lpColumn = 1 , lpStartByte = 419 , lpLength = 55 } + } + ] + , program_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 474 } + } diff --git a/test/testcase/Batsh/string.typed b/test/testcase/Batsh/string.typed new file mode 100644 index 0000000..d1a9ae7 --- /dev/null +++ b/test/testcase/Batsh/string.typed @@ -0,0 +1,1208 @@ +Program + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "BYVoid" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 1 + , lpColumn = 9 + , lpStartByte = 8 + , lpLength = 8 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 1 , lpColumn = 9 , lpStartByte = 8 , lpLength = 8 } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 17 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 18 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 18 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Slash/" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 27 + , lpLength = 8 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 2 + , lpColumn = 9 + , lpStartByte = 27 + , lpLength = 8 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 19 , lpLength = 17 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 19 , lpLength = 18 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 19 , lpLength = 18 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Backslash\\\\" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 46 + , lpLength = 13 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 46 + , lpLength = 13 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 22 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 23 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 3 , lpColumn = 1 , lpStartByte = 38 , lpLength = 23 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Quote\\\"'" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 70 + , lpLength = 10 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 70 + , lpLength = 10 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 62 , lpLength = 19 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 62 , lpLength = 20 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 4 , lpColumn = 1 , lpStartByte = 62 , lpLength = 20 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Literal + { expr_literal = + String + { literal_str = "Tab\\tTab" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 91 + , lpLength = 10 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 5 + , lpColumn = 9 + , lpStartByte = 91 + , lpLength = 10 + } + } + ] + , expr_annot = + TypeAnno + TString + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 83 , lpLength = 19 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 83 , lpLength = 20 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 5 , lpColumn = 1 , lpStartByte = 83 , lpLength = 20 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = "println(\"Newline\\nLine2\");" + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 104 , lpLength = 28 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 6 , lpColumn = 1 , lpStartByte = 104 , lpLength = 28 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = "println(\"!\");" + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 133 , lpLength = 15 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 7 , lpColumn = 1 , lpStartByte = 133 , lpLength = 15 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 8 + , lpColumn = 41 + , lpStartByte = 189 + , lpLength = 2 + } + } + , expr_left = + Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 8 + , lpColumn = 29 + , lpStartByte = 177 + , lpLength = 2 + } + } + , expr_left = + Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 8 + , lpColumn = 19 + , lpStartByte = 167 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "http://" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 157 + , lpLength = 9 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 157 + , lpLength = 9 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "www." + , literal_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 22 + , lpStartByte = 170 + , lpLength = 6 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 22 + , lpStartByte = 170 + , lpLength = 6 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 157 + , lpLength = 19 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "byvoid" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 32 + , lpStartByte = 180 + , lpLength = 8 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 32 + , lpStartByte = 180 + , lpLength = 8 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 157 + , lpLength = 31 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = ".com" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 44 + , lpStartByte = 192 + , lpLength = 6 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 44 + , lpStartByte = 192 + , lpLength = 6 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 + , lpColumn = 9 + , lpStartByte = 157 + , lpLength = 41 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 149 , lpLength = 50 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 149 , lpLength = 51 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 8 , lpColumn = 1 , lpStartByte = 149 , lpLength = 51 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 9 + , lpColumn = 27 + , lpStartByte = 227 + , lpLength = 2 + } + } + , expr_left = + Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 9 + , lpColumn = 15 + , lpStartByte = 215 + , lpLength = 2 + } + } + , expr_left = + Binary + { expr_binOp = + Divide + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 9 + , lpColumn = 11 + , lpStartByte = 211 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 6 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 209 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 209 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 2 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 13 + , lpStartByte = 213 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 13 + , lpStartByte = 213 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 209 + , lpLength = 5 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "BYVoid" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 9 + , lpColumn = 18 + , lpStartByte = 218 + , lpLength = 8 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 9 + , lpColumn = 18 + , lpStartByte = 218 + , lpLength = 8 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 209 + , lpLength = 17 + } + } + , expr_right = + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 9 + , lpColumn = 32 + , lpStartByte = 232 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 30 + , lpStartByte = 230 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 30 + , lpStartByte = 230 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 5 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 34 + , lpStartByte = 234 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 34 + , lpStartByte = 234 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 30 + , lpStartByte = 230 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 9 + , lpColumn = 9 + , lpStartByte = 209 + , lpLength = 26 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 201 , lpLength = 35 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 201 , lpLength = 36 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 9 , lpColumn = 1 , lpStartByte = 201 , lpLength = 36 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 10 + , lpColumn = 11 + , lpStartByte = 248 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 246 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 246 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "3" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 10 + , lpColumn = 13 + , lpStartByte = 250 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 10 + , lpColumn = 13 + , lpStartByte = 250 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 10 + , lpColumn = 9 + , lpStartByte = 246 + , lpLength = 7 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 238 , lpLength = 16 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 238 , lpLength = 17 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 238 , lpLength = 17 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 11 + , lpColumn = 17 + , lpStartByte = 272 + , lpLength = 2 + } + } + , expr_left = + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 11 + , lpColumn = 11 + , lpStartByte = 266 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 264 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 264 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "3" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 11 + , lpColumn = 13 + , lpStartByte = 268 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 11 + , lpColumn = 13 + , lpStartByte = 268 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 264 + , lpLength = 7 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "2" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 11 + , lpColumn = 20 + , lpStartByte = 275 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 11 + , lpColumn = 20 + , lpStartByte = 275 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 11 + , lpColumn = 9 + , lpStartByte = 264 + , lpLength = 14 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 256 , lpLength = 23 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 256 , lpLength = 24 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 256 , lpLength = 24 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 12 + , lpColumn = 11 + , lpStartByte = 291 + , lpLength = 1 + } + } + , expr_left = + Literal + { expr_literal = + Int + { literal_int = 3 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 289 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 289 + , lpLength = 1 + } + } + , expr_right = + Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 12 + , lpColumn = 18 + , lpStartByte = 298 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "3" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 12 + , lpColumn = 14 + , lpStartByte = 294 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 12 + , lpColumn = 14 + , lpStartByte = 294 + , lpLength = 3 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "2" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 12 + , lpColumn = 21 + , lpStartByte = 301 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 12 + , lpColumn = 21 + , lpStartByte = 301 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 12 + , lpColumn = 14 + , lpStartByte = 294 + , lpLength = 10 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 289 + , lpLength = 15 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 281 , lpLength = 25 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 281 , lpLength = 26 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 12 , lpColumn = 1 , lpStartByte = 281 , lpLength = 26 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ Binary + { expr_binOp = + Equal + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 13 + , lpColumn = 18 + , lpStartByte = 325 + , lpLength = 2 + } + } + , expr_left = + Literal + { expr_literal = + String + { literal_str = "BYVoid" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 316 + , lpLength = 8 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 316 + , lpLength = 8 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = "BYVoid" + , literal_annot = + TypeAnno + TString + LP + { lpLine = 13 + , lpColumn = 21 + , lpStartByte = 328 + , lpLength = 8 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 13 + , lpColumn = 21 + , lpStartByte = 328 + , lpLength = 8 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 13 + , lpColumn = 9 + , lpStartByte = 316 + , lpLength = 20 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 308 , lpLength = 29 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 308 , lpLength = 30 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 13 , lpColumn = 1 , lpStartByte = 308 , lpLength = 30 } + } + ] + , program_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 338 } + } diff --git a/test/testcase/Batsh/while.typed b/test/testcase/Batsh/while.typed new file mode 100644 index 0000000..434c83a --- /dev/null +++ b/test/testcase/Batsh/while.typed @@ -0,0 +1,1013 @@ +Program + { program_topls = + [ Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 1 + , lpColumn = 5 + , lpStartByte = 4 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 1 , lpColumn = 5 , lpStartByte = 4 , lpLength = 1 } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 5 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + While + { stmt_expr = + Binary + { expr_binOp = + Less + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 2 , lpColumn = 10 , lpStartByte = 16 , lpLength = 1 } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 2 + , lpColumn = 8 + , lpStartByte = 14 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 14 , lpLength = 1 } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 5 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 2 + , lpColumn = 12 + , lpStartByte = 18 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 2 , lpColumn = 12 , lpStartByte = 18 , lpLength = 1 } + } + , expr_annot = + TypeAnno + TBool + LP { lpLine = 2 , lpColumn = 8 , lpStartByte = 14 , lpLength = 5 } + } + , stmt_loop = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Call + { expr_func = "print" + , expr_params = + [ Binary + { expr_binOp = + Concat + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 3 + , lpColumn = 11 + , lpStartByte = 33 + , lpLength = 2 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 31 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 31 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + String + { literal_str = " " + , literal_annot = + TypeAnno + TString + LP + { lpLine = 3 + , lpColumn = 14 + , lpStartByte = 36 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 3 + , lpColumn = 14 + , lpStartByte = 36 + , lpLength = 3 + } + } + , expr_annot = + TypeAnno + TString + LP + { lpLine = 3 + , lpColumn = 9 + , lpStartByte = 31 + , lpLength = 8 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 3 + , lpColumn = 3 + , lpStartByte = 25 + , lpLength = 15 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 3 + , lpColumn = 3 + , lpStartByte = 25 + , lpLength = 16 + } + } + , Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 4 + , lpColumn = 3 + , lpStartByte = 44 + , lpLength = 1 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 4 + , lpColumn = 9 + , lpStartByte = 50 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 4 + , lpColumn = 7 + , lpStartByte = 48 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 4 + , lpColumn = 7 + , lpStartByte = 48 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 11 + , lpStartByte = 52 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 11 + , lpStartByte = 52 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 7 + , lpStartByte = 48 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 4 + , lpColumn = 3 + , lpStartByte = 44 + , lpLength = 9 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 4 + , lpColumn = 3 + , lpStartByte = 44 + , lpLength = 10 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 2 , lpColumn = 15 , lpStartByte = 21 , lpLength = 35 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 49 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 2 , lpColumn = 1 , lpStartByte = 7 , lpLength = 49 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = [] + , expr_annot = + TypeAnno + TString + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 57 , lpLength = 9 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 57 , lpLength = 10 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 6 , lpColumn = 1 , lpStartByte = 57 , lpLength = 10 } + } + , Statement + { toplevel_stmt = + Comment + { stmt_comment = " Fibonacci" + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 68 , lpLength = 12 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 7 , lpColumn = 1 , lpStartByte = 68 , lpLength = 12 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "n" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 8 + , lpColumn = 5 + , lpStartByte = 85 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 8 , lpColumn = 5 , lpStartByte = 85 , lpLength = 1 } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 5 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 6 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 8 , lpColumn = 1 , lpStartByte = 81 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 0 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 9 + , lpColumn = 5 + , lpStartByte = 92 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 9 , lpColumn = 5 , lpStartByte = 92 , lpLength = 1 } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 5 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 6 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 9 , lpColumn = 1 , lpStartByte = 88 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "j" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 1 } + } + , expr_subExpr = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 10 + , lpColumn = 5 + , lpStartByte = 99 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 10 , lpColumn = 5 , lpStartByte = 99 , lpLength = 1 } + } + , expr_annot = + TypeAnno + TInt + LP { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 5 } + } + , stmt_annot = + TypeAnno + TNoType + LP { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 6 } + } + , toplevel_annot = + TypeAnno + TNoType + LP { lpLine = 10 , lpColumn = 1 , lpStartByte = 95 , lpLength = 6 } + } + , Statement + { toplevel_stmt = + While + { stmt_expr = + Binary + { expr_binOp = + Less + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 11 + , lpColumn = 10 + , lpStartByte = 111 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "n" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 11 + , lpColumn = 8 + , lpStartByte = 109 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 11 + , lpColumn = 8 + , lpStartByte = 109 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 40 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 11 + , lpColumn = 12 + , lpStartByte = 113 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 11 + , lpColumn = 12 + , lpStartByte = 113 + , lpLength = 2 + } + } + , expr_annot = + TypeAnno + TBool + LP + { lpLine = 11 , lpColumn = 8 , lpStartByte = 109 , lpLength = 6 } + } + , stmt_loop = + Block + { stmt_stmts = + [ Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "k" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 12 + , lpColumn = 3 + , lpStartByte = 121 + , lpLength = 1 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 12 + , lpColumn = 9 + , lpStartByte = 127 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 12 + , lpColumn = 7 + , lpStartByte = 125 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 12 + , lpColumn = 7 + , lpStartByte = 125 + , lpLength = 1 + } + } + , expr_right = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "j" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 12 + , lpColumn = 11 + , lpStartByte = 129 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 12 + , lpColumn = 11 + , lpStartByte = 129 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 12 + , lpColumn = 7 + , lpStartByte = 125 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 12 + , lpColumn = 3 + , lpStartByte = 121 + , lpLength = 9 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 12 + , lpColumn = 3 + , lpStartByte = 121 + , lpLength = 10 + } + } + , Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "i" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 13 + , lpColumn = 3 + , lpStartByte = 134 + , lpLength = 1 + } + } + , expr_subExpr = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "j" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 13 + , lpColumn = 7 + , lpStartByte = 138 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 13 + , lpColumn = 7 + , lpStartByte = 138 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 13 + , lpColumn = 3 + , lpStartByte = 134 + , lpLength = 5 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 13 + , lpColumn = 3 + , lpStartByte = 134 + , lpLength = 6 + } + } + , Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "j" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 14 + , lpColumn = 3 + , lpStartByte = 143 + , lpLength = 1 + } + } + , expr_subExpr = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "k" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 14 + , lpColumn = 7 + , lpStartByte = 147 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 14 + , lpColumn = 7 + , lpStartByte = 147 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 14 + , lpColumn = 3 + , lpStartByte = 143 + , lpLength = 5 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 14 + , lpColumn = 3 + , lpStartByte = 143 + , lpLength = 6 + } + } + , Expression + { stmt_expr = + Assign + { expr_lvalue = + Identifier + { lvalue_ident = "n" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 15 + , lpColumn = 3 + , lpStartByte = 152 + , lpLength = 1 + } + } + , expr_subExpr = + Binary + { expr_binOp = + Plus + { binOp_annot = + TypeAnno + TNoType + LP + { lpLine = 15 + , lpColumn = 9 + , lpStartByte = 158 + , lpLength = 1 + } + } + , expr_left = + LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "n" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 15 + , lpColumn = 7 + , lpStartByte = 156 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 15 + , lpColumn = 7 + , lpStartByte = 156 + , lpLength = 1 + } + } + , expr_right = + Literal + { expr_literal = + Int + { literal_int = 1 + , literal_annot = + TypeAnno + TInt + LP + { lpLine = 15 + , lpColumn = 11 + , lpStartByte = 160 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 15 + , lpColumn = 11 + , lpStartByte = 160 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 15 + , lpColumn = 7 + , lpStartByte = 156 + , lpLength = 5 + } + } + , expr_annot = + TypeAnno + TInt + LP + { lpLine = 15 + , lpColumn = 3 + , lpStartByte = 152 + , lpLength = 9 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 15 + , lpColumn = 3 + , lpStartByte = 152 + , lpLength = 10 + } + } + , Expression + { stmt_expr = + Call + { expr_func = "println" + , expr_params = + [ LeftValue + { expr_lvalue = + Identifier + { lvalue_ident = "k" + , lvalue_annot = + TypeAnno + TVariable + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 173 + , lpLength = 1 + } + } + , expr_annot = + TypeAnno + TVariable + LP + { lpLine = 16 + , lpColumn = 11 + , lpStartByte = 173 + , lpLength = 1 + } + } + ] + , expr_annot = + TypeAnno + TString + LP + { lpLine = 16 + , lpColumn = 3 + , lpStartByte = 165 + , lpLength = 10 + } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 16 + , lpColumn = 3 + , lpStartByte = 165 + , lpLength = 11 + } + } + ] + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 16 , lpStartByte = 117 , lpLength = 61 } + } + , stmt_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 102 , lpLength = 76 } + } + , toplevel_annot = + TypeAnno + TNoType + LP + { lpLine = 11 , lpColumn = 1 , lpStartByte = 102 , lpLength = 76 } + } + ] + , program_annot = + TypeAnno + TNoType + LP { lpLine = 1 , lpColumn = 1 , lpStartByte = 0 , lpLength = 178 } + } From 876d3400a60040a87007515696a1729f5510c56c Mon Sep 17 00:00:00 2001 From: Carbo Kuo Date: Tue, 11 Nov 2014 21:40:22 +0100 Subject: [PATCH 53/53] Test generated typed ast --- test/TypeCheckTest.hs | 19 ++++++++++++++++++- test/UnitTest.hs | 3 ++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/test/TypeCheckTest.hs b/test/TypeCheckTest.hs index a8889e5..b3d852c 100644 --- a/test/TypeCheckTest.hs +++ b/test/TypeCheckTest.hs @@ -1,10 +1,11 @@ module TypeCheckTest where -import Batsh(parse) +import Batsh(parse, parseFromFile) import Batsh.Ast.Typed import Batsh.Token(LexPos(..)) import Batsh.TypeCheck import Control.Exception +import Control.Monad import Prelude hiding(catch) import Test.HUnit @@ -33,3 +34,19 @@ testTypeCheck = do assertEqual (show typedAst) expected typedAst handler :: (Eq a, Exception a) => a -> a -> IO () handler expected ex = assertEqual (show ex) expected ex + +testCaseDir = "test/testcase" +testCases = ["arith", "array", "assignment", "block", "command", "comment", + "exists", "function", "if", "recursion", "string", "while"] + +testTypeCheckFile :: Assertion +testTypeCheckFile = do + let testParseFile codeFile typedAstFile = do + text <- readFile typedAstFile + let expected = read text :: Program + ast <- parseFromFile codeFile + let typed = typeCheck ast + assertEqual (show typedAstFile) expected typed + forM_ testCases $ \testcase -> + testParseFile (testCaseDir ++ "/Batsh/" ++ testcase ++ ".batsh") + (testCaseDir ++ "/Batsh/" ++ testcase ++ ".typed") diff --git a/test/UnitTest.hs b/test/UnitTest.hs index 72681c7..b9576a5 100644 --- a/test/UnitTest.hs +++ b/test/UnitTest.hs @@ -16,5 +16,6 @@ main = defaultMainWithOpts testCase "Generator" GeneratorTest.testGenerator, testCase "SymbolTable" SymbolTableTest.testSymbolTable, testCase "SymbolTableFile" SymbolTableTest.testSymbolTableFile, - testCase "TypeCheck" TypeCheckTest.testTypeCheck] + testCase "TypeCheck" TypeCheckTest.testTypeCheck, + testCase "TypeCheckFile" TypeCheckTest.testTypeCheckFile] mempty