step
This commit is contained in:
parent
0d74456383
commit
73d5f08937
BIN
_build/.db
BIN
_build/.db
Binary file not shown.
Binary file not shown.
|
|
@ -1 +0,0 @@
|
||||||
Escaping the Dune sandbox
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -30,5 +30,7 @@ int main() {
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
match Spooky.parse_and_type_check sample_program with
|
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
|
| Error msg -> Printf.printf "Error: %s\n" msg
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -75,6 +75,86 @@ let string_of_typ =
|
||||||
in
|
in
|
||||||
go
|
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 =
|
let rec equal_typ a b =
|
||||||
match (a, b) with
|
match (a, b) with
|
||||||
| TInt, TInt | TBool, TBool | TVoid, TVoid -> true
|
| TInt, TInt | TBool, TBool | TVoid, TVoid -> true
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ type top =
|
||||||
type program = top list
|
type program = top list
|
||||||
|
|
||||||
val string_of_typ : typ -> string
|
val string_of_typ : typ -> string
|
||||||
|
val string_of_program : program -> string
|
||||||
val parse_string : string -> (program, string) result
|
val parse_string : string -> (program, string) result
|
||||||
val type_check : program -> (unit, string) result
|
val type_check : program -> (unit, string) result
|
||||||
val parse_and_type_check : string -> (program, string) result
|
val parse_and_type_check : string -> (program, string) result
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
|
@ -30,5 +30,7 @@ int main() {
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
match Spooky.parse_and_type_check sample_program with
|
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
|
| Error msg -> Printf.printf "Error: %s\n" msg
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,86 @@ let string_of_typ =
|
||||||
in
|
in
|
||||||
go
|
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 =
|
let rec equal_typ a b =
|
||||||
match (a, b) with
|
match (a, b) with
|
||||||
| TInt, TInt | TBool, TBool | TVoid, TVoid -> true
|
| TInt, TInt | TBool, TBool | TVoid, TVoid -> true
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ type top =
|
||||||
type program = top list
|
type program = top list
|
||||||
|
|
||||||
val string_of_typ : typ -> string
|
val string_of_typ : typ -> string
|
||||||
|
val string_of_program : program -> string
|
||||||
val parse_string : string -> (program, string) result
|
val parse_string : string -> (program, string) result
|
||||||
val type_check : program -> (unit, string) result
|
val type_check : program -> (unit, string) result
|
||||||
val parse_and_type_check : string -> (program, string) result
|
val parse_and_type_check : string -> (program, string) result
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue