compact compiler ids and spans to reduce memory usage
This commit is contained in:
+58
-52
@@ -13,8 +13,8 @@ Parser :: struct {
|
||||
source_file: ^source.Source,
|
||||
diagnostics: ^source.Diagnostics,
|
||||
module: ast.Module,
|
||||
pkg: int,
|
||||
file: int,
|
||||
pkg: ast.Package_Id,
|
||||
file: ast.File_Id,
|
||||
cursor: int,
|
||||
delimiter_depth: int,
|
||||
}
|
||||
@@ -22,10 +22,10 @@ Parser :: struct {
|
||||
MAX_EXPRESSION_NESTING :: 256
|
||||
|
||||
token_text :: proc(parser: ^Parser, tok: token.Token) -> string {
|
||||
if tok.span.start < 0 || tok.span.end < tok.span.start || tok.span.end > len(parser.source_file.text) {
|
||||
if tok.span.end < tok.span.start || int(tok.span.end) > len(parser.source_file.text) {
|
||||
return ""
|
||||
}
|
||||
return parser.source_file.text[tok.span.start:tok.span.end]
|
||||
return parser.source_file.text[int(tok.span.start):int(tok.span.end)]
|
||||
}
|
||||
|
||||
span_from :: proc(first, last: source.Span) -> source.Span {
|
||||
@@ -61,19 +61,19 @@ skip_newlines :: proc(parser: ^Parser) {
|
||||
}
|
||||
}
|
||||
|
||||
add_expr :: proc(parser: ^Parser, expr: ast.Expr) -> int {
|
||||
id := len(parser.module.exprs)
|
||||
add_expr :: proc(parser: ^Parser, expr: ast.Expr) -> ast.Expr_Id {
|
||||
id := ast.expr_id(len(parser.module.exprs))
|
||||
append(&parser.module.exprs, expr)
|
||||
return id
|
||||
}
|
||||
|
||||
invalid_expr :: proc(parser: ^Parser, span: source.Span, message: string) -> int {
|
||||
invalid_expr :: proc(parser: ^Parser, span: source.Span, message: string) -> ast.Expr_Id {
|
||||
id := source.add(parser.diagnostics, span, message)
|
||||
return add_expr(parser, ast.Expr{
|
||||
kind=.Invalid,
|
||||
span=span,
|
||||
left=ast.INVALID_ID,
|
||||
right=ast.INVALID_ID,
|
||||
left=ast.INVALID_EXPR,
|
||||
right=ast.INVALID_EXPR,
|
||||
diagnostic=id,
|
||||
})
|
||||
}
|
||||
@@ -131,7 +131,7 @@ skip_parenthesized :: proc(parser: ^Parser) -> source.Span {
|
||||
return span_from(start.span, end.span)
|
||||
}
|
||||
|
||||
parse_call :: proc(parser: ^Parser, qualifier: symbol.Id, first, name: token.Token, nesting: int) -> int {
|
||||
parse_call :: proc(parser: ^Parser, qualifier: symbol.Id, first, name: token.Token, nesting: int) -> ast.Expr_Id {
|
||||
if nesting >= MAX_EXPRESSION_NESTING {
|
||||
span := skip_parenthesized(parser)
|
||||
return invalid_expr(parser, span, "expression nesting exceeds 256 levels")
|
||||
@@ -139,7 +139,7 @@ parse_call :: proc(parser: ^Parser, qualifier: symbol.Id, first, name: token.Tok
|
||||
left_paren := advance(parser)
|
||||
parser.delimiter_depth += 1
|
||||
defer parser.delimiter_depth -= 1
|
||||
args: [dynamic]int
|
||||
args: [dynamic]ast.Expr_Id
|
||||
args.allocator = parser.module.allocator
|
||||
skip_newlines(parser)
|
||||
for current(parser).kind != .Right_Paren && current(parser).kind != .Eof {
|
||||
@@ -162,13 +162,13 @@ parse_call :: proc(parser: ^Parser, qualifier: symbol.Id, first, name: token.Tok
|
||||
qualifier=qualifier,
|
||||
name=name.symbol,
|
||||
args=args[:],
|
||||
left=ast.INVALID_ID,
|
||||
right=ast.INVALID_ID,
|
||||
diagnostic=-1,
|
||||
left=ast.INVALID_EXPR,
|
||||
right=ast.INVALID_EXPR,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
}
|
||||
|
||||
parse_primary :: proc(parser: ^Parser, nesting: int) -> int {
|
||||
parse_primary :: proc(parser: ^Parser, nesting: int) -> ast.Expr_Id {
|
||||
tok := current(parser)
|
||||
#partial switch tok.kind {
|
||||
case .Integer:
|
||||
@@ -181,9 +181,9 @@ parse_primary :: proc(parser: ^Parser, nesting: int) -> int {
|
||||
kind=.Integer,
|
||||
span=tok.span,
|
||||
integer=value,
|
||||
left=ast.INVALID_ID,
|
||||
right=ast.INVALID_ID,
|
||||
diagnostic=-1,
|
||||
left=ast.INVALID_EXPR,
|
||||
right=ast.INVALID_EXPR,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
case .Identifier:
|
||||
first := advance(parser)
|
||||
@@ -204,9 +204,9 @@ parse_primary :: proc(parser: ^Parser, nesting: int) -> int {
|
||||
span=span_from(first.span, name.span),
|
||||
qualifier=qualifier,
|
||||
name=name.symbol,
|
||||
left=ast.INVALID_ID,
|
||||
right=ast.INVALID_ID,
|
||||
diagnostic=-1,
|
||||
left=ast.INVALID_EXPR,
|
||||
right=ast.INVALID_EXPR,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
case .Underscore:
|
||||
advance(parser)
|
||||
@@ -231,8 +231,8 @@ parse_primary :: proc(parser: ^Parser, nesting: int) -> int {
|
||||
return add_expr(parser, ast.Expr{
|
||||
kind=.Invalid,
|
||||
span=tok.span,
|
||||
left=ast.INVALID_ID,
|
||||
right=ast.INVALID_ID,
|
||||
left=ast.INVALID_EXPR,
|
||||
right=ast.INVALID_EXPR,
|
||||
diagnostic=tok.diagnostic,
|
||||
})
|
||||
}
|
||||
@@ -250,7 +250,7 @@ infix_binding_power :: proc(kind: token.Kind) -> (left, right: int, ok: bool) {
|
||||
return 0, 0, false
|
||||
}
|
||||
|
||||
parse_expression_bp :: proc(parser: ^Parser, minimum_binding_power, nesting: int) -> int {
|
||||
parse_expression_bp :: proc(parser: ^Parser, minimum_binding_power, nesting: int) -> ast.Expr_Id {
|
||||
if nesting > MAX_EXPRESSION_NESTING {
|
||||
tok := current(parser)
|
||||
if tok.kind != .Newline && tok.kind != .Right_Brace && tok.kind != .Eof {
|
||||
@@ -277,7 +277,7 @@ parse_expression_bp :: proc(parser: ^Parser, minimum_binding_power, nesting: int
|
||||
span=span_from(left_expr.span, right_expr.span),
|
||||
left=left,
|
||||
right=right,
|
||||
diagnostic=-1,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
if parser.delimiter_depth > 0 {
|
||||
skip_newlines(parser)
|
||||
@@ -286,17 +286,17 @@ parse_expression_bp :: proc(parser: ^Parser, minimum_binding_power, nesting: int
|
||||
return left
|
||||
}
|
||||
|
||||
parse_expression :: proc(parser: ^Parser) -> int {
|
||||
parse_expression :: proc(parser: ^Parser) -> ast.Expr_Id {
|
||||
return parse_expression_bp(parser, 0, 0)
|
||||
}
|
||||
|
||||
finish_statement :: proc(parser: ^Parser, allow_closing_brace := false) -> int {
|
||||
finish_statement :: proc(parser: ^Parser, allow_closing_brace := false) -> source.Diagnostic_Id {
|
||||
if current(parser).kind == .Newline {
|
||||
skip_newlines(parser)
|
||||
return -1
|
||||
return source.INVALID_DIAGNOSTIC
|
||||
}
|
||||
if current(parser).kind == .Eof || allow_closing_brace && current(parser).kind == .Right_Brace {
|
||||
return -1
|
||||
return source.INVALID_DIAGNOSTIC
|
||||
}
|
||||
diagnostic := source.add(
|
||||
parser.diagnostics,
|
||||
@@ -312,33 +312,33 @@ finish_statement :: proc(parser: ^Parser, allow_closing_brace := false) -> int {
|
||||
return diagnostic
|
||||
}
|
||||
|
||||
parse_return :: proc(parser: ^Parser) -> int {
|
||||
parse_return :: proc(parser: ^Parser) -> ast.Stmt_Id {
|
||||
start := advance(parser)
|
||||
skip_newlines(parser)
|
||||
if current(parser).kind == .Underscore {
|
||||
end := advance(parser)
|
||||
id := len(parser.module.statements)
|
||||
id := ast.stmt_id(len(parser.module.statements))
|
||||
append(&parser.module.statements, ast.Stmt{
|
||||
kind=.Return,
|
||||
span=span_from(start.span, end.span),
|
||||
name=end.symbol,
|
||||
expr=ast.INVALID_ID,
|
||||
diagnostic=-1,
|
||||
expr=ast.INVALID_EXPR,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
return id
|
||||
}
|
||||
expr := parse_expression(parser)
|
||||
id := len(parser.module.statements)
|
||||
id := ast.stmt_id(len(parser.module.statements))
|
||||
append(&parser.module.statements, ast.Stmt{
|
||||
kind=.Return,
|
||||
span=span_from(start.span, parser.module.exprs[expr].span),
|
||||
expr=expr,
|
||||
diagnostic=-1,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
return id
|
||||
}
|
||||
|
||||
parse_statement :: proc(parser: ^Parser) -> int {
|
||||
parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
|
||||
if current(parser).kind == .Keyword_Return {
|
||||
return parse_return(parser)
|
||||
}
|
||||
@@ -363,7 +363,7 @@ parse_statement :: proc(parser: ^Parser) -> int {
|
||||
kind = .Declaration
|
||||
immutable = operator.kind == .Colon_Colon
|
||||
}
|
||||
id := len(parser.module.statements)
|
||||
id := ast.stmt_id(len(parser.module.statements))
|
||||
append(&parser.module.statements, ast.Stmt{
|
||||
kind=kind,
|
||||
span=span_from(name.span, parser.module.exprs[expr].span),
|
||||
@@ -371,7 +371,7 @@ parse_statement :: proc(parser: ^Parser) -> int {
|
||||
type=type_syntax,
|
||||
immutable=immutable,
|
||||
expr=expr,
|
||||
diagnostic=-1,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
return id
|
||||
}
|
||||
@@ -379,12 +379,12 @@ parse_statement :: proc(parser: ^Parser) -> int {
|
||||
}
|
||||
|
||||
expr := parse_expression(parser)
|
||||
id := len(parser.module.statements)
|
||||
id := ast.stmt_id(len(parser.module.statements))
|
||||
append(&parser.module.statements, ast.Stmt{
|
||||
kind=.Expression,
|
||||
span=parser.module.exprs[expr].span,
|
||||
expr=expr,
|
||||
diagnostic=-1,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
return id
|
||||
}
|
||||
@@ -446,6 +446,7 @@ parse_function :: proc(parser: ^Parser, name: token.Token, c_abi: bool) {
|
||||
if !ended_by_newline && current(parser).kind != .Eof {
|
||||
_ = finish_statement(parser)
|
||||
}
|
||||
_ = ast.function_id(len(parser.module.functions))
|
||||
append(&parser.module.functions, ast.Function{
|
||||
span=span_from(name.span, end.span),
|
||||
name=name.symbol,
|
||||
@@ -455,23 +456,23 @@ parse_function :: proc(parser: ^Parser, name: token.Token, c_abi: bool) {
|
||||
has_body=false,
|
||||
params=params,
|
||||
result=result,
|
||||
diagnostic=-1,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
return
|
||||
}
|
||||
advance(parser)
|
||||
|
||||
body: [dynamic]int
|
||||
body: [dynamic]ast.Stmt_Id
|
||||
body.allocator = parser.module.allocator
|
||||
skip_newlines(parser)
|
||||
for current(parser).kind != .Right_Brace && current(parser).kind != .Eof {
|
||||
append(&body, parse_statement(parser))
|
||||
if diagnostic := finish_statement(parser, true); diagnostic >= 0 {
|
||||
statement_id := len(parser.module.statements)
|
||||
if diagnostic := finish_statement(parser, true); diagnostic != source.INVALID_DIAGNOSTIC {
|
||||
statement_id := ast.stmt_id(len(parser.module.statements))
|
||||
append(&parser.module.statements, ast.Stmt{
|
||||
kind=.Invalid,
|
||||
span=current(parser).span,
|
||||
expr=ast.INVALID_ID,
|
||||
expr=ast.INVALID_EXPR,
|
||||
diagnostic=diagnostic,
|
||||
})
|
||||
append(&body, statement_id)
|
||||
@@ -482,6 +483,7 @@ parse_function :: proc(parser: ^Parser, name: token.Token, c_abi: bool) {
|
||||
source.add(parser.diagnostics, current(parser).span, "expected '}' after function body")
|
||||
end = func_token
|
||||
}
|
||||
_ = ast.function_id(len(parser.module.functions))
|
||||
append(&parser.module.functions, ast.Function{
|
||||
span=span_from(name.span, end.span),
|
||||
name=name.symbol,
|
||||
@@ -492,7 +494,7 @@ parse_function :: proc(parser: ^Parser, name: token.Token, c_abi: bool) {
|
||||
params=params,
|
||||
result=result,
|
||||
body=body[:],
|
||||
diagnostic=-1,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -522,28 +524,30 @@ parse_import :: proc(parser: ^Parser, alias: token.Token, start: token.Token) {
|
||||
if path_token.kind != .Newline && path_token.kind != .Eof {
|
||||
advance(parser)
|
||||
}
|
||||
_ = ast.import_id(len(parser.module.imports))
|
||||
append(&parser.module.imports, ast.Import{
|
||||
span=start.span,
|
||||
alias=alias.symbol,
|
||||
pkg=parser.pkg,
|
||||
file=parser.file,
|
||||
target=-1,
|
||||
target=ast.INVALID_PACKAGE,
|
||||
valid=false,
|
||||
diagnostic=-1,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
_ = finish_statement(parser)
|
||||
return
|
||||
}
|
||||
advance(parser)
|
||||
_ = ast.import_id(len(parser.module.imports))
|
||||
append(&parser.module.imports, ast.Import{
|
||||
span=span_from(start.span, path_token.span),
|
||||
alias=alias.symbol,
|
||||
path=decode_import_path(parser, path_token),
|
||||
pkg=parser.pkg,
|
||||
file=parser.file,
|
||||
target=-1,
|
||||
target=ast.INVALID_PACKAGE,
|
||||
valid=true,
|
||||
diagnostic=-1,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
_ = finish_statement(parser)
|
||||
}
|
||||
@@ -606,6 +610,7 @@ parse_top_level :: proc(parser: ^Parser) {
|
||||
}
|
||||
|
||||
expr := parse_expression(parser)
|
||||
_ = ast.global_id(len(parser.module.globals))
|
||||
append(&parser.module.globals, ast.Global{
|
||||
span=span_from(name.span, parser.module.exprs[expr].span),
|
||||
name=name.symbol,
|
||||
@@ -614,7 +619,7 @@ parse_top_level :: proc(parser: ^Parser) {
|
||||
type=type_syntax,
|
||||
immutable=operator.kind == .Colon_Colon,
|
||||
expr=expr,
|
||||
diagnostic=-1,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
})
|
||||
_ = finish_statement(parser)
|
||||
}
|
||||
@@ -644,7 +649,8 @@ parse_into :: proc(
|
||||
source_file: ^source.Source,
|
||||
diagnostics: ^source.Diagnostics,
|
||||
module: ^ast.Module,
|
||||
pkg, file: int,
|
||||
pkg: ast.Package_Id,
|
||||
file: ast.File_Id,
|
||||
) {
|
||||
parser := Parser{
|
||||
tokens=stream,
|
||||
|
||||
Reference in New Issue
Block a user