Node :: struct {
lit: string,
derived_node : Any_Node,
}
Statement :: struct {
using node: Node,
derived_stmt : Any_Stmt,
}
EOF_Stmt :: struct {
using node: Node,
}
Expression :: struct {
using node: Node,
}
Identifier :: struct {
tok: tok.Token
}
LetStmt :: struct {
using stmt: Statement,
let_tok: tok.Token,
name: ^Identifier,
exp: ^Expression,
}
Bad_Stmt :: struct {
using stmt: Statement,
}
Any_Node :: union{
^LetStmt,
^EOF_Stmt,
^Bad_Stmt,
}
Any_Stmt :: union {
^LetStmt,
^EOF_Stmt,
^Bad_Stmt,
}
new_node:: proc($T: typeid) -> ^T {
n, _ := new(T)
n.derived_node = n
base: ^Node = n // dummy check
when intrinsics.type_has_field(T, "derived_expr") {
n.derived_expr = n
}
when intrinsics.type_has_field(T, "derived_stmt") {
n.derived_stmt = n
}
return n
}
using the style of ast in core:odin.
parse_program :: proc(p: ^Parser) -> (^Program, ParsingError) {
prog := new(Program)
for p.cur_tok.type != .EOF {
stmt := parse_statement(p)
append(&prog.stmts, stmt)
}
return prog, .OK
}
parse_statement :: proc(p: ^Parser) -> ^ast.Statement {
if p.cur_tok.type == .LET {
t_stmt := ast.new_node(ast.LetStmt)
t_stmt.let_tok = p.cur_tok
t_stmt.name = get_identifier(p)
if p.next_tok.type != .ASSIGN {next_token(p);return ast.new_node(ast.Bad_Stmt)}
exp := get_expression(p)
return t_stmt
}
next_token(p)
return ast.new_node(ast.Bad_Stmt)
}
get_identifier :: proc(p: ^Parser) -> ^ast.Identifier {
next_token(p)
ident := new(ast.Identifier)
ident.tok = p.cur_tok
return ident
}
get_expression :: proc(p: ^Parser) -> ^ast.Expression {
next_token(p)
return nil
}
getting
[WARN ] --- [2024-12-28 12:36:03] < 576B/ 616B> < 616B> ( 1/ 12) :: parser.my_test
+++ leak 40B @ 0x1D2723E4078 [token.odin:90:make_new_lexer()]
+++ leak 88B @ 0x1D2723E4118 [ast.odin:44:new_node()]
+++ leak 24B @ 0x1D2723E4178 [parser.odin:53:get_identifier()]
+++ leak 64B @ 0x1D2723E4198 [parser.odin:33:parse_program()]
+++ leak 88B @ 0x1D2723E4250 [ast.odin:44:new_node()]
+++ leak 24B @ 0x1D2723E42B0 [parser.odin:53:get_identifier()]
+++ leak 48B @ 0x1D2723E42D0 [ast.odin:44:new_node()]
+++ leak 48B @ 0x1D2723E4308 [ast.odin:44:new_node()]
+++ leak 48B @ 0x1D2723E41E0 [ast.odin:44:new_node()]
+++ leak 48B @ 0x1D2723E4218 [ast.odin:44:new_node()]
+++ leak 56B @ 0x1D2723E40A8 [parser.odin:13:make_new_parser()]
parser [| ] 1 :: [package done] (1 failed)
Finished 1 test in 3.135ms. The test failed.
from this
@(test)
my_test :: proc(t: ^testing.T) {
l := tok.make_new_lexer(
input = ` let five = 5
let ten = 10
`,
)
p := make_new_parser(l)
program, err := parse_program(p)
defer free(program)
defer free_all(context.temp_allocator)
for v, i in program.stmts {
es, es_ok := v.derived_stmt.(^ast.LetStmt)
testing.expectf(t, es_ok, "Token reading faild. Token was %v", program.stmts)
}
}
test.
Some memory questions. in
Program :: struct {
stmts: [dynamic]^ast.Statement,
}
do i have to make() the dynamic array like prog.stmts = make([dynamic]^ast.Statement)
? if do/dont it works either way.
if i want to free(let_statement)
LetStmt :: struct {
using stmt: Statement,
let_tok: tok.Token,
name: ^Identifier,
exp: ^Expression,
}
do those name
exp
pointers also get deleted? if i delete something how do i find out if it got deleted? just assign somehting to the pointer and see if throws exception?
if it does not delete inner pointers how do i clean up something like this : stmts: [dynamic]^ast.Statement
which will hold multiple types of statements which points to other expressin etc.?
I could not find or understand where is the memory cleanup in the "core:odin/parser"
packages or in the test file. That would answer all my questions.
And in
new_node:: proc($T: typeid) -> ^T {
n, _ := new(T)
n.derived_node = n
base: ^Node = n // dummy check
when intrinsics.type_has_field(T, "derived_expr") {
n.derived_expr = n
}
when intrinsics.type_has_field(T, "derived_stmt") {
n.derived_stmt = n
}
return n
}
this, i tried new_node:: proc($T: typeid/Node) -> ^T {
but if i do ast.new_node(ast.LetStmt)
could not convert to type Node
. But i thought it should. Because LetStmt
is using stmt: Statement,
and Statement
is using node: Node
.
Please ignore wrong logics of the code. I was just getting something to run first. And trying use polymorphic stuff in ast.