diff --git a/_build/.actions/default/test/runtest-test_spooky-95b7c3def6e74394d89edf8a77d85a3c b/_build/.actions/default/test/runtest-test_spooky-95b7c3def6e74394d89edf8a77d85a3c deleted file mode 100644 index e69de29..0000000 diff --git a/_build/.db b/_build/.db index d46c565..a92e5c1 100644 Binary files a/_build/.db and b/_build/.db differ diff --git a/_build/.digest-db b/_build/.digest-db index cf2e0cf..6c4640d 100644 Binary files a/_build/.digest-db and b/_build/.digest-db differ diff --git a/_build/.sandbox/.hg/requires b/_build/.sandbox/.hg/requires deleted file mode 100644 index 387e851..0000000 --- a/_build/.sandbox/.hg/requires +++ /dev/null @@ -1 +0,0 @@ -Escaping the Dune sandbox \ No newline at end of file diff --git a/_build/default/bin/.main.eobjs/native/dune__exe__Main.cmx b/_build/default/bin/.main.eobjs/native/dune__exe__Main.cmx index c270bad..e3a821d 100644 Binary files a/_build/default/bin/.main.eobjs/native/dune__exe__Main.cmx and b/_build/default/bin/.main.eobjs/native/dune__exe__Main.cmx differ diff --git a/_build/default/bin/.main.eobjs/native/dune__exe__Main.o b/_build/default/bin/.main.eobjs/native/dune__exe__Main.o index 770f015..494b498 100644 Binary files a/_build/default/bin/.main.eobjs/native/dune__exe__Main.o and b/_build/default/bin/.main.eobjs/native/dune__exe__Main.o differ diff --git a/_build/default/bin/main.exe b/_build/default/bin/main.exe index 557db63..3777ac0 100755 Binary files a/_build/default/bin/main.exe and b/_build/default/bin/main.exe differ diff --git a/_build/default/bin/main.ml b/_build/default/bin/main.ml index 4b4feb7..46289d0 100644 --- a/_build/default/bin/main.ml +++ b/_build/default/bin/main.ml @@ -30,5 +30,7 @@ int main() { let () = match Spooky.parse_and_type_check sample_program with - | Ok _ -> print_endline "Program parsed and type-checked successfully." + | Ok ast -> + Printf.printf "Program parsed and type-checked successfully.\n\n"; + Printf.printf "Parsed AST:\n%s\n" (Spooky.string_of_program ast) | Error msg -> Printf.printf "Error: %s\n" msg diff --git a/_build/default/lib/.spooky.objs/byte/spooky.cmi b/_build/default/lib/.spooky.objs/byte/spooky.cmi index cbcd5c7..459bc5e 100644 Binary files a/_build/default/lib/.spooky.objs/byte/spooky.cmi and b/_build/default/lib/.spooky.objs/byte/spooky.cmi differ diff --git a/_build/default/lib/.spooky.objs/byte/spooky.cmo b/_build/default/lib/.spooky.objs/byte/spooky.cmo index f00b4a7..ad429c5 100644 Binary files a/_build/default/lib/.spooky.objs/byte/spooky.cmo and b/_build/default/lib/.spooky.objs/byte/spooky.cmo differ diff --git a/_build/default/lib/.spooky.objs/byte/spooky.cmt b/_build/default/lib/.spooky.objs/byte/spooky.cmt index 5d256e4..d19864f 100644 Binary files a/_build/default/lib/.spooky.objs/byte/spooky.cmt and b/_build/default/lib/.spooky.objs/byte/spooky.cmt differ diff --git a/_build/default/lib/.spooky.objs/byte/spooky.cmti b/_build/default/lib/.spooky.objs/byte/spooky.cmti index 4d7abac..fac86d6 100644 Binary files a/_build/default/lib/.spooky.objs/byte/spooky.cmti and b/_build/default/lib/.spooky.objs/byte/spooky.cmti differ diff --git a/_build/default/lib/.spooky.objs/native/spooky.cmx b/_build/default/lib/.spooky.objs/native/spooky.cmx index f867437..d3be128 100644 Binary files a/_build/default/lib/.spooky.objs/native/spooky.cmx and b/_build/default/lib/.spooky.objs/native/spooky.cmx differ diff --git a/_build/default/lib/.spooky.objs/native/spooky.o b/_build/default/lib/.spooky.objs/native/spooky.o index d07c845..4b7719f 100644 Binary files a/_build/default/lib/.spooky.objs/native/spooky.o and b/_build/default/lib/.spooky.objs/native/spooky.o differ diff --git a/_build/default/lib/spooky.a b/_build/default/lib/spooky.a index 3cabf78..9dd1688 100644 Binary files a/_build/default/lib/spooky.a and b/_build/default/lib/spooky.a differ diff --git a/_build/default/lib/spooky.cma b/_build/default/lib/spooky.cma index b622c3d..ddd1e04 100644 Binary files a/_build/default/lib/spooky.cma and b/_build/default/lib/spooky.cma differ diff --git a/_build/default/lib/spooky.cmxa b/_build/default/lib/spooky.cmxa index 481bdbd..4b3c7d5 100644 Binary files a/_build/default/lib/spooky.cmxa and b/_build/default/lib/spooky.cmxa differ diff --git a/_build/default/lib/spooky.cmxs b/_build/default/lib/spooky.cmxs index 8bdc305..4b8799a 100755 Binary files a/_build/default/lib/spooky.cmxs and b/_build/default/lib/spooky.cmxs differ diff --git a/_build/default/lib/spooky.ml b/_build/default/lib/spooky.ml index dd8a47a..e0f55e0 100644 --- a/_build/default/lib/spooky.ml +++ b/_build/default/lib/spooky.ml @@ -75,6 +75,86 @@ let string_of_typ = in go +let string_of_binop = function + | Add -> "+" + | Sub -> "-" + | Mul -> "*" + | Div -> "/" + | Mod -> "%" + | And -> "&&" + | Or -> "||" + | Eq -> "==" + | Ne -> "!=" + | Lt -> "<" + | Le -> "<=" + | Gt -> ">" + | Ge -> ">=" + +let string_of_unop = function Neg -> "-" | Not -> "!" + +let rec string_of_expr = function + | IntLit n -> Printf.sprintf "IntLit(%d)" n + | BoolLit b -> Printf.sprintf "BoolLit(%b)" b + | Var v -> Printf.sprintf "Var(%s)" v + | Binop (op, a, b) -> + Printf.sprintf "Binop(%s, %s, %s)" (string_of_binop op) (string_of_expr a) (string_of_expr b) + | Unop (op, e) -> Printf.sprintf "Unop(%s, %s)" (string_of_unop op) (string_of_expr e) + | Assign (lhs, rhs) -> Printf.sprintf "Assign(%s, %s)" (string_of_expr lhs) (string_of_expr rhs) + | Call (callee, args) -> + let args_s = String.concat ", " (List.map string_of_expr args) in + Printf.sprintf "Call(%s, [%s])" (string_of_expr callee) args_s + | ArrayGet (arr, idx) -> Printf.sprintf "ArrayGet(%s, %s)" (string_of_expr arr) (string_of_expr idx) + | StructGet (obj, fld) -> Printf.sprintf "StructGet(%s, %s)" (string_of_expr obj) fld + +let indent n = String.make (2 * n) ' ' + +let rec string_of_stmt ?(level = 0) st = + let i = indent level in + match st with + | VarDecl (t, n, None) -> Printf.sprintf "%sVarDecl(%s %s)" i (string_of_typ t) n + | VarDecl (t, n, Some e) -> + Printf.sprintf "%sVarDecl(%s %s = %s)" i (string_of_typ t) n (string_of_expr e) + | Expr e -> Printf.sprintf "%sExpr(%s)" i (string_of_expr e) + | Return None -> Printf.sprintf "%sReturn" i + | Return (Some e) -> Printf.sprintf "%sReturn(%s)" i (string_of_expr e) + | Block body -> + let body_s = String.concat "\n" (List.map (string_of_stmt ~level:(level + 1)) body) in + if String.equal body_s "" then Printf.sprintf "%sBlock" i + else Printf.sprintf "%sBlock\n%s" i body_s + | If (cond, tbranch, ebranch) -> + let then_s = String.concat "\n" (List.map (string_of_stmt ~level:(level + 1)) tbranch) in + let else_s = String.concat "\n" (List.map (string_of_stmt ~level:(level + 1)) ebranch) in + if ebranch = [] then Printf.sprintf "%sIf(%s)\n%s" i (string_of_expr cond) then_s + else Printf.sprintf "%sIf(%s)\n%s\n%sElse\n%s" i (string_of_expr cond) then_s i else_s + | ForEach (it_t, it_name, iterable, body) -> + let body_s = String.concat "\n" (List.map (string_of_stmt ~level:(level + 1)) body) in + Printf.sprintf "%sForEach(%s %s in %s)\n%s" i (string_of_typ it_t) it_name (string_of_expr iterable) + body_s + +let string_of_top = function + | TopStruct s -> + let fields = + s.fields |> List.map (fun (t, n) -> Printf.sprintf " Field(%s %s)" (string_of_typ t) n) + |> String.concat "\n" + in + if String.equal fields "" then Printf.sprintf "Struct %s" s.sname + else Printf.sprintf "Struct %s\n%s" s.sname fields + | TopGlobalVar (t, n, init) -> + (match init with + | None -> Printf.sprintf "GlobalVar(%s %s)" (string_of_typ t) n + | Some e -> Printf.sprintf "GlobalVar(%s %s = %s)" (string_of_typ t) n (string_of_expr e)) + | TopFunc f -> + let params = + f.params + |> List.map (fun (t, n) -> Printf.sprintf "%s %s" (string_of_typ t) n) + |> String.concat ", " + in + let body = String.concat "\n" (List.map (string_of_stmt ~level:1) f.body) in + if String.equal body "" then Printf.sprintf "Function %s(%s) -> %s" f.name params (string_of_typ f.ret) + else Printf.sprintf "Function %s(%s) -> %s\n%s" f.name params (string_of_typ f.ret) body + +let string_of_program (prog : program) = prog |> List.map string_of_top |> String.concat "\n\n" + let rec equal_typ a b = match (a, b) with | TInt, TInt | TBool, TBool | TVoid, TVoid -> true diff --git a/_build/default/lib/spooky.mli b/_build/default/lib/spooky.mli index a62ed34..c0b4748 100644 --- a/_build/default/lib/spooky.mli +++ b/_build/default/lib/spooky.mli @@ -61,6 +61,7 @@ type top = type program = top list val string_of_typ : typ -> string +val string_of_program : program -> string val parse_string : string -> (program, string) result val type_check : program -> (unit, string) result val parse_and_type_check : string -> (program, string) result diff --git a/_build/default/test/.test_spooky.eobjs/native/dune__exe__Test_spooky.cmx b/_build/default/test/.test_spooky.eobjs/native/dune__exe__Test_spooky.cmx index 2994701..b9fbb91 100644 Binary files a/_build/default/test/.test_spooky.eobjs/native/dune__exe__Test_spooky.cmx and b/_build/default/test/.test_spooky.eobjs/native/dune__exe__Test_spooky.cmx differ diff --git a/_build/default/test/.test_spooky.eobjs/native/dune__exe__Test_spooky.o b/_build/default/test/.test_spooky.eobjs/native/dune__exe__Test_spooky.o index 1a5ed76..baa7409 100644 Binary files a/_build/default/test/.test_spooky.eobjs/native/dune__exe__Test_spooky.o and b/_build/default/test/.test_spooky.eobjs/native/dune__exe__Test_spooky.o differ diff --git a/_build/default/test/test_spooky.exe b/_build/default/test/test_spooky.exe index 8ff9ec4..98ad7fe 100755 Binary files a/_build/default/test/test_spooky.exe and b/_build/default/test/test_spooky.exe differ diff --git a/_build/trace.csexp b/_build/trace.csexp index 3591f11..fcda99f 100644 --- a/_build/trace.csexp +++ b/_build/trace.csexp @@ -1 +1 @@ -(6:config4:init19:1777475932353986185(7:version6:3.22.2)(9:build_dir6:_build)(4:argv(4:dune4:exec6:spooky))(3:env(18:DIRENV_LOG_FORMAT=65:FZF_DEFAULT_COMMAND=rg --files --hidden --follow --glob "!.git/*"140:CAML_LD_LIBRARY_PATH=/home/steve/.opam/default/lib/stublibs:/home/steve/.opam/default/lib/ocaml/stublibs:/home/steve/.opam/default/lib/ocaml10:USER=steve60:OCAMLTOP_INCLUDE_PATH=/home/steve/.opam/default/lib/toplevel37:PWD=/home/steve/projects/ocaml/spooky153:VSCODE_GIT_ASKPASS_MAIN=/home/steve/.vscode-server/cli/servers/Stable-10c8e557c8b9f9ed0a87f61f1c9a44bde731c409/server/extensions/git/dist/askpass-main.js22:XDG_SESSION_CLASS=user11:VISUAL=nvim28:TERM_PROGRAM_VERSION=1.117.080:OPAM_LAST_ENV=/home/steve/.opam/.last-env/env-550cde22b571c5ee951c5aa1091061dc-017:XDG_SESSION_ID=2787:VSCODE_IPC_HOOK_CLI=/run/user/1000/vscode-ipc-0974db83-8f7b-46f1-a5db-f5ac1fc5b845.sock63:VSCODE_GIT_IPC_HANDLE=/run/user/1000/vscode-git-7fc91d943b.sock19:COLORTERM=truecolor11:EDITOR=nvim150:CODELLDB_LAUNCH_CONNECT_FILE=/home/steve/.vscode-server/data/User/workspaceStorage/803f4dd44aeb4117289049d18054ecce/vadimcn.vscode-lldb/rpcaddress.txt33:ANDROID_NDK_HOME=/opt/android-ndk30:VSCODE_GIT_ASKPASS_EXTRA_ARGS=16:HOME=/home/steve38:MANPATH=:/home/steve/.opam/default/man19:TERM=xterm-256color122:VSCODE_GIT_ASKPASS_NODE=/home/steve/.vscode-server/cli/servers/Stable-10c8e557c8b9f9ed0a87f61f1c9a44bde731c409/server/node136:GIT_ASKPASS=/home/steve/.vscode-server/cli/servers/Stable-10c8e557c8b9f9ed0a87f61f1c9a44bde731c409/server/extensions/git/dist/askpass.sh18:VSCODE_INJECTION=128:MPS_JDK=/opt/MPS 2021.3/jbr/64:XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop44:OPAM_SWITCH_PREFIX=/home/steve/.opam/default124:BROWSER=/home/steve/.vscode-server/cli/servers/Stable-10c8e557c8b9f9ed0a87f61f1c9a44bde731c409/server/bin/helpers/browser.sh26:MAIL=/var/spool/mail/steve7:SHLVL=331:FLYCTL_INSTALL=/home/steve/.fly19:SHELL=/usr/bin/fish52:SSH_CONNECTION=84.115.232.107 53606 65.21.205.199 222511:PATH=/home/steve/.opam/default/bin:/home/steve/.vscode-server/data/User/globalStorage/github.copilot-chat/debugCommand:/home/steve/.vscode-server/data/User/globalStorage/github.copilot-chat/copilotCli:/home/steve/.vscode-server/extensions/vadimcn.vscode-lldb-1.12.1/bin:/home/steve/.vscode-server/extensions/vadimcn.vscode-lldb-1.12.1/bin:/home/steve/.vscode-server/data/User/globalStorage/github.copilot-chat/debugCommand:/home/steve/.vscode-server/data/User/globalStorage/github.copilot-chat/copilotCli:/home/steve/.vscode-server/cli/servers/Stable-10c8e557c8b9f9ed0a87f61f1c9a44bde731c409/server/bin/remote-cli:/usr/local/sbin:/usr/local/bin:/usr/bin:/opt/riscv/bin:/home/steve/.npm/bin:/home/steve/.cargo/bin:/home/steve/scripts:/home/steve/bin:/home/steve/go/bin:/usr/local/go/bin:/home/steve/.fluvio/bin:/home/steve/.local/share/ponyup/bin:/home/steve/NuSMV-2.6.0-Linux/bin/:/home/steve/.local/bin:/home/steve/.vino/bin:/home/steve/projects/odin/Odin:/home/steve/j90x/bin:/home/steve/opt/GNAT/2021/bin:/home/steve/opt/GNAT/2021-arm-elf/bin:/home/steve/opt/GNAT/arm-gnueabihf//bin:/home/steve/.fly/bin:/home/steve/.platformio/penv/bin:/home/steve/.ghcup/bin/:/home/steve/.wasmer/bin/:/home/steve/.roswell/bin:/home/steve/.emacs.d/bin:/var/lib/snapd/snap/bin:/opt/riscv/bin:/home/steve/.npm/bin:/home/steve/.cargo/bin:/home/steve/scripts:/home/steve/bin:/home/steve/go/bin:/usr/local/go/bin:/home/steve/.fluvio/bin:/home/steve/.local/share/ponyup/bin:/home/steve/NuSMV-2.6.0-Linux/bin/:/home/steve/.local/bin:/home/steve/.vino/bin:/home/steve/projects/odin/Odin:/home/steve/j90x/bin:/home/steve/opt/GNAT/2021/bin:/home/steve/opt/GNAT/2021-arm-elf/bin:/home/steve/opt/GNAT/arm-gnueabihf//bin:/home/steve/.fly/bin:/home/steve/.platformio/penv/bin:/home/steve/.ghcup/bin/:/home/steve/.wasmer/bin/:/home/steve/.roswell/bin:/home/steve/.emacs.d/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/usr/lib/rustup/bin:/opt/riscv/bin:/home/steve/.npm/bin:/home/steve/.cargo/bin:/home/steve/scripts:/home/steve/bin:/home/steve/go/bin:/usr/local/go/bin:/home/steve/.fluvio/bin:/home/steve/.local/share/ponyup/bin:/home/steve/NuSMV-2.6.0-Linux/bin/:/home/steve/.local/bin:/home/steve/.vino/bin:/home/steve/projects/odin/Odin:/home/steve/j90x/bin:/home/steve/opt/GNAT/2021/bin:/home/steve/opt/GNAT/2021-arm-elf/bin:/home/steve/opt/GNAT/arm-gnueabihf//bin:/home/steve/.fly/bin:/home/steve/.platformio/penv/bin:/home/steve/.ghcup/bin/:/home/steve/.wasmer/bin/:/home/steve/.roswell/bin:/home/steve/.emacs.d/bin53:DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus14:MOTD_SHOWN=pam20:XDG_SESSION_TYPE=tty20:OPAMNOENVNOTICE=true13:LOGNAME=steve19:SYSTEMD_EDITOR=nvim30:XDG_RUNTIME_DIR=/run/user/100034:SSH_CLIENT=84.115.232.107 53606 2229:ANDROID_HOME=/opt/android-sdk58:OCAML_TOPLEVEL_PATH=/home/steve/.opam/default/lib/toplevel37:STARSHIP_SESSION_KEY=381514717543912119:STARSHIP_SHELL=fish19:TERM_PROGRAM=vscode16:LANG=en_US.UTF-834:VSCODE_PYTHON_AUTOACTIVATE_GUARD=1))(4:root33:/home/steve/projects/ocaml/spooky)(3:pid7:1715249)(11:initial_cwd33:/home/steve/projects/ocaml/spooky)(5:start19:1777475932350049571))(3:log4:info19:1777475932354011645(7:message10:ocamlparam)(10:OCAMLPARAM5:unset))(6:thread12:spawn_thread19:1777475932354041375(4:name7:console))(3:log4:info19:1777475932354132486(7:message20:Shared cache enabled)(13:cache_enabled25:Enabled_except_user_rules))(3:log4:info19:1777475932354140246(7:message21:Shared cache location)(8:root_dir26:/home/steve/.cache/dune/db))(3:log4:info19:1777475932354235907(7:message14:Workspace root)(4:root33:/home/steve/projects/ocaml/spooky))(3:log4:info19:1777475932355021974(7:message25:Auto-detected concurrency)(11:concurrency2:12))(6:thread12:spawn_thread19:1777475932355044474(4:name14:signal-watcher))(7:process15:signal_received19:1777475932355199305(6:signal4:CHLD))(10:persistent2:db(19:17774759323552869065:54791)(4:path17:_build/.digest-db)(6:module9:DIGEST-DB)(9:operation4:load))(3:log4:info19:1777475932355499258(7:message12:Dune context)(7:context((4:name7:default)(4:kind7:default)(7:profile3:Dev)(6:merlin4:true)(14:fdo_target_exe())(9:build_dir(12:In_build_dir7:default))(15:instrument_with()))))(5:rules9:Dune load(19:17774759323555212286:118811)(3:dir1:.))(7:process5:start19:1777475932355849301(12:process_args(7:-config))(3:pid7:1715254)(10:categories())(6:queued3:810)(4:prog40:/home/steve/.opam/default/bin/ocamlc.opt)(3:dir1:.))(7:process15:signal_received19:1777475932360582522(6:signal4:CHLD))(7:process6:finish(19:17774759323558493017:4783742)(12:process_args(7:-config))(3:pid7:1715254)(10:categories())(4:prog40:/home/steve/.opam/default/bin/ocamlc.opt)(3:dir1:.)(4:exit1:0)(6:rusage((13:user_cpu_time6:921000)(15:system_cpu_time7:3685000)(6:maxrss5:26848)(6:minflt4:1155)(6:majflt1:0)(7:inblock1:0)(7:oublock1:0)(5:nvcsw1:1)(6:nivcsw1:0))))(10:persistent2:db(19:17774759323625502095:21471)(4:path10:_build/.db)(6:module14:INCREMENTAL-DB)(9:operation4:load))(7:process5:start19:1777475932365512925(12:process_args(12:-short-paths10:-keep-locs11:-warn-error2:+a2:-g10:-bin-annot22:-bin-annot-occurrences2:-I20:bin/.main.eobjs/byte2:-I21:lib/.spooky.objs/byte14:-no-alias-deps7:-opaque2:-o40:bin/.main.eobjs/byte/dune__exe__Main.cmi2:-c5:-intf12:bin/main.mli))(3:pid7:1715255)(10:categories())(6:queued3:890)(4:prog40:/home/steve/.opam/default/bin/ocamlc.opt)(3:dir14:_build/default)(12:target_files(55:_build/default/bin/.main.eobjs/byte/dune__exe__Main.cmi56:_build/default/bin/.main.eobjs/byte/dune__exe__Main.cmti)))(7:process15:signal_received19:1777475932372781388(6:signal4:CHLD))(7:process6:finish(19:17774759323655129257:7323364)(12:process_args(12:-short-paths10:-keep-locs11:-warn-error2:+a2:-g10:-bin-annot22:-bin-annot-occurrences2:-I20:bin/.main.eobjs/byte2:-I21:lib/.spooky.objs/byte14:-no-alias-deps7:-opaque2:-o40:bin/.main.eobjs/byte/dune__exe__Main.cmi2:-c5:-intf12:bin/main.mli))(3:pid7:1715255)(10:categories())(4:prog40:/home/steve/.opam/default/bin/ocamlc.opt)(3:dir14:_build/default)(4:exit1:0)(12:target_files(55:_build/default/bin/.main.eobjs/byte/dune__exe__Main.cmi56:_build/default/bin/.main.eobjs/byte/dune__exe__Main.cmti))(6:rusage((13:user_cpu_time7:2168000)(15:system_cpu_time7:4955000)(6:maxrss5:27360)(6:minflt4:1629)(6:majflt1:0)(7:inblock1:0)(7:oublock2:16)(5:nvcsw1:1)(6:nivcsw1:1))))(7:process5:start19:1777475932373080151(12:process_args(12:-short-paths10:-keep-locs11:-warn-error2:+a2:-g2:-I20:bin/.main.eobjs/byte2:-I22:bin/.main.eobjs/native2:-I21:lib/.spooky.objs/byte2:-I23:lib/.spooky.objs/native9:-cmi-file40:bin/.main.eobjs/byte/dune__exe__Main.cmi14:-no-alias-deps7:-opaque2:-o42:bin/.main.eobjs/native/dune__exe__Main.cmx2:-c5:-impl11:bin/main.ml))(3:pid7:1715256)(10:categories())(6:queued3:670)(4:prog42:/home/steve/.opam/default/bin/ocamlopt.opt)(3:dir14:_build/default)(12:target_files(57:_build/default/bin/.main.eobjs/native/dune__exe__Main.cmx55:_build/default/bin/.main.eobjs/native/dune__exe__Main.o)))(7:process15:signal_received19:1777475932387505066(6:signal4:CHLD))(7:process6:finish(19:17774759323730801518:14476406)(12:process_args(12:-short-paths10:-keep-locs11:-warn-error2:+a2:-g2:-I20:bin/.main.eobjs/byte2:-I22:bin/.main.eobjs/native2:-I21:lib/.spooky.objs/byte2:-I23:lib/.spooky.objs/native9:-cmi-file40:bin/.main.eobjs/byte/dune__exe__Main.cmi14:-no-alias-deps7:-opaque2:-o42:bin/.main.eobjs/native/dune__exe__Main.cmx2:-c5:-impl11:bin/main.ml))(3:pid7:1715256)(10:categories())(4:prog42:/home/steve/.opam/default/bin/ocamlopt.opt)(3:dir14:_build/default)(4:exit1:0)(12:target_files(57:_build/default/bin/.main.eobjs/native/dune__exe__Main.cmx55:_build/default/bin/.main.eobjs/native/dune__exe__Main.o))(6:rusage((13:user_cpu_time7:5975000)(15:system_cpu_time7:8299000)(6:maxrss5:27360)(6:minflt4:2477)(6:majflt1:0)(7:inblock1:0)(7:oublock2:24)(5:nvcsw1:4)(6:nivcsw1:1))))(7:process5:start19:1777475932388223672(12:process_args(12:-short-paths10:-keep-locs11:-warn-error2:+a2:-g2:-o12:bin/main.exe15:lib/spooky.cmxa42:bin/.main.eobjs/native/dune__exe__Main.cmx))(3:pid7:1715258)(10:categories())(6:queued3:770)(4:prog42:/home/steve/.opam/default/bin/ocamlopt.opt)(3:dir14:_build/default)(12:target_files(27:_build/default/bin/main.exe)))(7:process15:signal_received19:1777475932520221300(6:signal4:CHLD))(7:process6:finish(19:17774759323882236729:132048958)(12:process_args(12:-short-paths10:-keep-locs11:-warn-error2:+a2:-g2:-o12:bin/main.exe15:lib/spooky.cmxa42:bin/.main.eobjs/native/dune__exe__Main.cmx))(3:pid7:1715258)(10:categories())(4:prog42:/home/steve/.opam/default/bin/ocamlopt.opt)(3:dir14:_build/default)(4:exit1:0)(12:target_files(27:_build/default/bin/main.exe))(6:rusage((13:user_cpu_time8:73077000)(15:system_cpu_time8:58134000)(6:maxrss5:27360)(6:minflt4:8920)(6:majflt1:0)(7:inblock1:0)(7:oublock4:5488)(5:nvcsw2:13)(6:nivcsw1:8))))(10:persistent2:db(19:17774759325377446225:97261)(4:path17:_build/.digest-db)(6:module9:DIGEST-DB)(9:operation4:save))(10:persistent2:db(19:17774759325378673835:45571)(4:path10:_build/.db)(6:module14:INCREMENTAL-DB)(9:operation4:save))(6:config4:exit19:1777475932537922054(2:gc((10:stack_size1:0)(10:heap_words6:373048)(14:top_heap_words6:373048)(11:minor_words7:917495.)(11:major_words7:277000.)(14:promoted_words7:263034.)(11:compactions1:0)(17:major_collections1:3)(17:minor_collections1:5)))(2:io((10:files_read((5:count1:8)(4:time6:159251)(5:bytes3:538)))(13:files_written((5:count1:1)(4:time1:0)(5:bytes1:7)))(16:directories_read((5:count1:1)(4:time1:0)))))(6:digest((5:files((5:count1:9)(4:time7:1832546)(5:bytes1:0)))(6:values((5:count2:52)(4:time5:66590)(5:bytes5:13044)))))) \ No newline at end of file +(6:config4:init19:1777476517247843124(7:version6:3.22.2)(9:build_dir6:_build)(4:argv(4:dune4:exec6:spooky))(3:env(33:ANDROID_NDK_HOME=/opt/android-ndk20:XDG_SESSION_TYPE=tty52:SSH_CONNECTION=84.115.232.107 53606 65.21.205.199 22140:CAML_LD_LIBRARY_PATH=/home/steve/.opam/default/lib/stublibs:/home/steve/.opam/default/lib/ocaml/stublibs:/home/steve/.opam/default/lib/ocaml18:DIRENV_LOG_FORMAT=28:MPS_JDK=/opt/MPS 2021.3/jbr/22:XDG_SESSION_CLASS=user153:VSCODE_GIT_ASKPASS_MAIN=/home/steve/.vscode-server/cli/servers/Stable-10c8e557c8b9f9ed0a87f61f1c9a44bde731c409/server/extensions/git/dist/askpass-main.js53:DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus30:XDG_RUNTIME_DIR=/run/user/100028:TERM_PROGRAM_VERSION=1.117.060:OCAMLTOP_INCLUDE_PATH=/home/steve/.opam/default/lib/toplevel16:LANG=en_US.UTF-834:VSCODE_PYTHON_AUTOACTIVATE_GUARD=119:SYSTEMD_EDITOR=nvim2511:PATH=/home/steve/.opam/default/bin:/home/steve/.vscode-server/data/User/globalStorage/github.copilot-chat/debugCommand:/home/steve/.vscode-server/data/User/globalStorage/github.copilot-chat/copilotCli:/home/steve/.vscode-server/extensions/vadimcn.vscode-lldb-1.12.1/bin:/home/steve/.vscode-server/extensions/vadimcn.vscode-lldb-1.12.1/bin:/home/steve/.vscode-server/data/User/globalStorage/github.copilot-chat/debugCommand:/home/steve/.vscode-server/data/User/globalStorage/github.copilot-chat/copilotCli:/home/steve/.vscode-server/cli/servers/Stable-10c8e557c8b9f9ed0a87f61f1c9a44bde731c409/server/bin/remote-cli:/usr/local/sbin:/usr/local/bin:/usr/bin:/opt/riscv/bin:/home/steve/.npm/bin:/home/steve/.cargo/bin:/home/steve/scripts:/home/steve/bin:/home/steve/go/bin:/usr/local/go/bin:/home/steve/.fluvio/bin:/home/steve/.local/share/ponyup/bin:/home/steve/NuSMV-2.6.0-Linux/bin/:/home/steve/.local/bin:/home/steve/.vino/bin:/home/steve/projects/odin/Odin:/home/steve/j90x/bin:/home/steve/opt/GNAT/2021/bin:/home/steve/opt/GNAT/2021-arm-elf/bin:/home/steve/opt/GNAT/arm-gnueabihf//bin:/home/steve/.fly/bin:/home/steve/.platformio/penv/bin:/home/steve/.ghcup/bin/:/home/steve/.wasmer/bin/:/home/steve/.roswell/bin:/home/steve/.emacs.d/bin:/var/lib/snapd/snap/bin:/opt/riscv/bin:/home/steve/.npm/bin:/home/steve/.cargo/bin:/home/steve/scripts:/home/steve/bin:/home/steve/go/bin:/usr/local/go/bin:/home/steve/.fluvio/bin:/home/steve/.local/share/ponyup/bin:/home/steve/NuSMV-2.6.0-Linux/bin/:/home/steve/.local/bin:/home/steve/.vino/bin:/home/steve/projects/odin/Odin:/home/steve/j90x/bin:/home/steve/opt/GNAT/2021/bin:/home/steve/opt/GNAT/2021-arm-elf/bin:/home/steve/opt/GNAT/arm-gnueabihf//bin:/home/steve/.fly/bin:/home/steve/.platformio/penv/bin:/home/steve/.ghcup/bin/:/home/steve/.wasmer/bin/:/home/steve/.roswell/bin:/home/steve/.emacs.d/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/usr/lib/rustup/bin:/opt/riscv/bin:/home/steve/.npm/bin:/home/steve/.cargo/bin:/home/steve/scripts:/home/steve/bin:/home/steve/go/bin:/usr/local/go/bin:/home/steve/.fluvio/bin:/home/steve/.local/share/ponyup/bin:/home/steve/NuSMV-2.6.0-Linux/bin/:/home/steve/.local/bin:/home/steve/.vino/bin:/home/steve/projects/odin/Odin:/home/steve/j90x/bin:/home/steve/opt/GNAT/2021/bin:/home/steve/opt/GNAT/2021-arm-elf/bin:/home/steve/opt/GNAT/arm-gnueabihf//bin:/home/steve/.fly/bin:/home/steve/.platformio/penv/bin:/home/steve/.ghcup/bin/:/home/steve/.wasmer/bin/:/home/steve/.roswell/bin:/home/steve/.emacs.d/bin19:TERM_PROGRAM=vscode13:LOGNAME=steve7:SHLVL=311:VISUAL=nvim63:VSCODE_GIT_IPC_HANDLE=/run/user/1000/vscode-git-7fc91d943b.sock34:SSH_CLIENT=84.115.232.107 53606 22122:VSCODE_GIT_ASKPASS_NODE=/home/steve/.vscode-server/cli/servers/Stable-10c8e557c8b9f9ed0a87f61f1c9a44bde731c409/server/node37:PWD=/home/steve/projects/ocaml/spooky80:OPAM_LAST_ENV=/home/steve/.opam/.last-env/env-550cde22b571c5ee951c5aa1091061dc-065:FZF_DEFAULT_COMMAND=rg --files --hidden --follow --glob "!.git/*"30:VSCODE_GIT_ASKPASS_EXTRA_ARGS=29:ANDROID_HOME=/opt/android-sdk17:XDG_SESSION_ID=2719:STARSHIP_SHELL=fish124:BROWSER=/home/steve/.vscode-server/cli/servers/Stable-10c8e557c8b9f9ed0a87f61f1c9a44bde731c409/server/bin/helpers/browser.sh37:STARSHIP_SESSION_KEY=381514717543912158:OCAML_TOPLEVEL_PATH=/home/steve/.opam/default/lib/toplevel136:GIT_ASKPASS=/home/steve/.vscode-server/cli/servers/Stable-10c8e557c8b9f9ed0a87f61f1c9a44bde731c409/server/extensions/git/dist/askpass.sh10:USER=steve44:OPAM_SWITCH_PREFIX=/home/steve/.opam/default38:MANPATH=:/home/steve/.opam/default/man14:MOTD_SHOWN=pam16:HOME=/home/steve31:FLYCTL_INSTALL=/home/steve/.fly20:OPAMNOENVNOTICE=true19:TERM=xterm-256color87:VSCODE_IPC_HOOK_CLI=/run/user/1000/vscode-ipc-0974db83-8f7b-46f1-a5db-f5ac1fc5b845.sock19:COLORTERM=truecolor19:SHELL=/usr/bin/fish26:MAIL=/var/spool/mail/steve11:EDITOR=nvim64:XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop150:CODELLDB_LAUNCH_CONNECT_FILE=/home/steve/.vscode-server/data/User/workspaceStorage/803f4dd44aeb4117289049d18054ecce/vadimcn.vscode-lldb/rpcaddress.txt18:VSCODE_INJECTION=1))(4:root33:/home/steve/projects/ocaml/spooky)(3:pid7:1719226)(11:initial_cwd33:/home/steve/projects/ocaml/spooky)(5:start19:1777476517243937930))(3:log4:info19:1777476517247870504(7:message10:ocamlparam)(10:OCAMLPARAM5:unset))(6:thread12:spawn_thread19:1777476517247903075(4:name7:console))(3:log4:info19:1777476517248024396(7:message20:Shared cache enabled)(13:cache_enabled25:Enabled_except_user_rules))(3:log4:info19:1777476517248034036(7:message21:Shared cache location)(8:root_dir26:/home/steve/.cache/dune/db))(3:log4:info19:1777476517248050326(7:message14:Workspace root)(4:root33:/home/steve/projects/ocaml/spooky))(3:log4:info19:1777476517248806052(7:message25:Auto-detected concurrency)(11:concurrency2:12))(6:thread12:spawn_thread19:1777476517248827182(4:name14:signal-watcher))(7:process15:signal_received19:1777476517248966054(6:signal4:CHLD))(10:persistent2:db(19:17774765172490558645:62811)(4:path17:_build/.digest-db)(6:module9:DIGEST-DB)(9:operation4:load))(3:log4:info19:1777476517249287316(7:message12:Dune context)(7:context((4:name7:default)(4:kind7:default)(7:profile3:Dev)(6:merlin4:true)(14:fdo_target_exe())(9:build_dir(12:In_build_dir7:default))(15:instrument_with()))))(5:rules9:Dune load(19:17774765172493093276:120251)(3:dir1:.))(7:process5:start19:1777476517249657460(12:process_args(7:-config))(3:pid7:1719231)(10:categories())(6:queued3:820)(4:prog40:/home/steve/.opam/default/bin/ocamlc.opt)(3:dir1:.))(7:process15:signal_received19:1777476517254495581(6:signal4:CHLD))(7:process6:finish(19:17774765172496574607:4881072)(12:process_args(7:-config))(3:pid7:1719231)(10:categories())(4:prog40:/home/steve/.opam/default/bin/ocamlc.opt)(3:dir1:.)(4:exit1:0)(6:rusage((13:user_cpu_time6:947000)(15:system_cpu_time7:3782000)(6:maxrss5:27052)(6:minflt4:1152)(6:majflt1:0)(7:inblock1:0)(7:oublock1:0)(5:nvcsw1:1)(6:nivcsw1:0))))(10:persistent2:db(19:17774765172564528885:31131)(4:path10:_build/.db)(6:module14:INCREMENTAL-DB)(9:operation4:load))(10:persistent2:db(19:17774765172668997786:113111)(4:path17:_build/.digest-db)(6:module9:DIGEST-DB)(9:operation4:save))(6:config4:exit19:1777476517267041130(2:gc((10:stack_size1:0)(10:heap_words6:373048)(14:top_heap_words6:373048)(11:minor_words7:917491.)(11:major_words7:277171.)(14:promoted_words7:263253.)(11:compactions1:0)(17:major_collections1:3)(17:minor_collections1:5)))(2:io((10:files_read((5:count1:2)(4:time7:1943206)(5:bytes3:538)))(13:files_written((5:count1:1)(4:time1:0)(5:bytes1:7)))(16:directories_read((5:count1:1)(4:time1:0)))))(6:digest((5:files((5:count1:3)(4:time5:53541)(5:bytes1:0)))(6:values((5:count2:52)(4:time5:58400)(5:bytes5:12846)))))) \ No newline at end of file diff --git a/bin/main.ml b/bin/main.ml index 58b561a..46289d0 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -30,5 +30,7 @@ int main() { let () = match Spooky.parse_and_type_check sample_program with - | Ok ast -> Printf.printf "Program parsed and type-checked successfully.\n" + | Ok ast -> + Printf.printf "Program parsed and type-checked successfully.\n\n"; + Printf.printf "Parsed AST:\n%s\n" (Spooky.string_of_program ast) | Error msg -> Printf.printf "Error: %s\n" msg diff --git a/lib/spooky.ml b/lib/spooky.ml index dd8a47a..e0f55e0 100644 --- a/lib/spooky.ml +++ b/lib/spooky.ml @@ -75,6 +75,86 @@ let string_of_typ = in go +let string_of_binop = function + | Add -> "+" + | Sub -> "-" + | Mul -> "*" + | Div -> "/" + | Mod -> "%" + | And -> "&&" + | Or -> "||" + | Eq -> "==" + | Ne -> "!=" + | Lt -> "<" + | Le -> "<=" + | Gt -> ">" + | Ge -> ">=" + +let string_of_unop = function Neg -> "-" | Not -> "!" + +let rec string_of_expr = function + | IntLit n -> Printf.sprintf "IntLit(%d)" n + | BoolLit b -> Printf.sprintf "BoolLit(%b)" b + | Var v -> Printf.sprintf "Var(%s)" v + | Binop (op, a, b) -> + Printf.sprintf "Binop(%s, %s, %s)" (string_of_binop op) (string_of_expr a) (string_of_expr b) + | Unop (op, e) -> Printf.sprintf "Unop(%s, %s)" (string_of_unop op) (string_of_expr e) + | Assign (lhs, rhs) -> Printf.sprintf "Assign(%s, %s)" (string_of_expr lhs) (string_of_expr rhs) + | Call (callee, args) -> + let args_s = String.concat ", " (List.map string_of_expr args) in + Printf.sprintf "Call(%s, [%s])" (string_of_expr callee) args_s + | ArrayGet (arr, idx) -> Printf.sprintf "ArrayGet(%s, %s)" (string_of_expr arr) (string_of_expr idx) + | StructGet (obj, fld) -> Printf.sprintf "StructGet(%s, %s)" (string_of_expr obj) fld + +let indent n = String.make (2 * n) ' ' + +let rec string_of_stmt ?(level = 0) st = + let i = indent level in + match st with + | VarDecl (t, n, None) -> Printf.sprintf "%sVarDecl(%s %s)" i (string_of_typ t) n + | VarDecl (t, n, Some e) -> + Printf.sprintf "%sVarDecl(%s %s = %s)" i (string_of_typ t) n (string_of_expr e) + | Expr e -> Printf.sprintf "%sExpr(%s)" i (string_of_expr e) + | Return None -> Printf.sprintf "%sReturn" i + | Return (Some e) -> Printf.sprintf "%sReturn(%s)" i (string_of_expr e) + | Block body -> + let body_s = String.concat "\n" (List.map (string_of_stmt ~level:(level + 1)) body) in + if String.equal body_s "" then Printf.sprintf "%sBlock" i + else Printf.sprintf "%sBlock\n%s" i body_s + | If (cond, tbranch, ebranch) -> + let then_s = String.concat "\n" (List.map (string_of_stmt ~level:(level + 1)) tbranch) in + let else_s = String.concat "\n" (List.map (string_of_stmt ~level:(level + 1)) ebranch) in + if ebranch = [] then Printf.sprintf "%sIf(%s)\n%s" i (string_of_expr cond) then_s + else Printf.sprintf "%sIf(%s)\n%s\n%sElse\n%s" i (string_of_expr cond) then_s i else_s + | ForEach (it_t, it_name, iterable, body) -> + let body_s = String.concat "\n" (List.map (string_of_stmt ~level:(level + 1)) body) in + Printf.sprintf "%sForEach(%s %s in %s)\n%s" i (string_of_typ it_t) it_name (string_of_expr iterable) + body_s + +let string_of_top = function + | TopStruct s -> + let fields = + s.fields |> List.map (fun (t, n) -> Printf.sprintf " Field(%s %s)" (string_of_typ t) n) + |> String.concat "\n" + in + if String.equal fields "" then Printf.sprintf "Struct %s" s.sname + else Printf.sprintf "Struct %s\n%s" s.sname fields + | TopGlobalVar (t, n, init) -> + (match init with + | None -> Printf.sprintf "GlobalVar(%s %s)" (string_of_typ t) n + | Some e -> Printf.sprintf "GlobalVar(%s %s = %s)" (string_of_typ t) n (string_of_expr e)) + | TopFunc f -> + let params = + f.params + |> List.map (fun (t, n) -> Printf.sprintf "%s %s" (string_of_typ t) n) + |> String.concat ", " + in + let body = String.concat "\n" (List.map (string_of_stmt ~level:1) f.body) in + if String.equal body "" then Printf.sprintf "Function %s(%s) -> %s" f.name params (string_of_typ f.ret) + else Printf.sprintf "Function %s(%s) -> %s\n%s" f.name params (string_of_typ f.ret) body + +let string_of_program (prog : program) = prog |> List.map string_of_top |> String.concat "\n\n" + let rec equal_typ a b = match (a, b) with | TInt, TInt | TBool, TBool | TVoid, TVoid -> true diff --git a/lib/spooky.mli b/lib/spooky.mli index a62ed34..c0b4748 100644 --- a/lib/spooky.mli +++ b/lib/spooky.mli @@ -61,6 +61,7 @@ type top = type program = top list val string_of_typ : typ -> string +val string_of_program : program -> string val parse_string : string -> (program, string) result val type_check : program -> (unit, string) result val parse_and_type_check : string -> (program, string) result