move vm to x
This commit is contained in:
parent
90590b964a
commit
3adbcab494
5 changed files with 259 additions and 151 deletions
|
|
@ -1,94 +0,0 @@
|
||||||
// #module_parameters(RUN_TESTS := false);
|
|
||||||
|
|
||||||
#load "parser.jai";
|
|
||||||
#load "interp.jai";
|
|
||||||
|
|
||||||
#scope_module;
|
|
||||||
|
|
||||||
// exported to the entire module since we want these everywhere
|
|
||||||
|
|
||||||
mem :: #import "jc/memory";
|
|
||||||
array :: #import "jc/array";
|
|
||||||
kv :: #import "jc/kv";
|
|
||||||
|
|
||||||
basic :: #import "Basic"; // @future
|
|
||||||
strings :: #import "String"; // @future
|
|
||||||
|
|
||||||
#scope_file;
|
|
||||||
|
|
||||||
#run {
|
|
||||||
parser: Parser;
|
|
||||||
ok := parse_string(*parser, #string END
|
|
||||||
fn add(l, r) do return l + r end
|
|
||||||
fn sub(l, r) do return l - r end
|
|
||||||
fn mul(l, r) do return l * r end
|
|
||||||
fn div(l, r) do return l / r end
|
|
||||||
|
|
||||||
var x = 21.0
|
|
||||||
var y = 22.0
|
|
||||||
var z = x + y
|
|
||||||
|
|
||||||
x = x + 1.0 / 2.0
|
|
||||||
print x
|
|
||||||
|
|
||||||
x = add(x, div(1.0, 2.0))
|
|
||||||
print x
|
|
||||||
|
|
||||||
print x == x
|
|
||||||
print x == y
|
|
||||||
print x == z
|
|
||||||
|
|
||||||
assert x == y
|
|
||||||
assert x != z
|
|
||||||
|
|
||||||
// def (
|
|
||||||
// Add = poly[T] proc(x T, y T) T do return x + y end
|
|
||||||
// Sub = poly[T] proc(x T, y T) T do return x - y end
|
|
||||||
// Mul = poly[T] proc(x T, y T) T do return x * y end
|
|
||||||
// Div = poly[T] proc(x T, y T) T do return x / y end
|
|
||||||
// )
|
|
||||||
|
|
||||||
// def (
|
|
||||||
// Addi = Add[int]
|
|
||||||
// Addf = Add[float]
|
|
||||||
// Subi = Sub[int]
|
|
||||||
// Subf = Sub[float]
|
|
||||||
// Muli = Mul[int]
|
|
||||||
// Mulf = Mul[float]
|
|
||||||
// Divi = Div[int]
|
|
||||||
// Divf = Div[float]
|
|
||||||
// )
|
|
||||||
|
|
||||||
// def Foo = struct {
|
|
||||||
// x int = 1
|
|
||||||
// y int = 2
|
|
||||||
// z int = 3
|
|
||||||
// }
|
|
||||||
|
|
||||||
// def Value = union {
|
|
||||||
// i int
|
|
||||||
// f float
|
|
||||||
// b bool
|
|
||||||
// }
|
|
||||||
|
|
||||||
// def Kind = enum {
|
|
||||||
// a
|
|
||||||
// b
|
|
||||||
// c
|
|
||||||
// d
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var foo = Foo{ x = 10, y = 20, z = 30 }
|
|
||||||
// var val = Value{ f = 3.14 }
|
|
||||||
// var kind = Kind.a
|
|
||||||
END);
|
|
||||||
|
|
||||||
interp: Interp;
|
|
||||||
interp.toplevel = parser.toplevel;
|
|
||||||
|
|
||||||
interp_program(*interp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// #if RUN_TESTS {
|
|
||||||
// test :: #import "jc/test";
|
|
||||||
// }
|
|
||||||
|
|
@ -1,10 +1,3 @@
|
||||||
Interp :: struct {
|
|
||||||
allocator: Allocator;
|
|
||||||
|
|
||||||
toplevel: []*Node;
|
|
||||||
global: *Interp_Scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
Interp_Scope :: struct {
|
Interp_Scope :: struct {
|
||||||
parent: *Interp_Scope;
|
parent: *Interp_Scope;
|
||||||
bindings: kv.Kv(string, *Interp_Value);
|
bindings: kv.Kv(string, *Interp_Value);
|
||||||
|
|
@ -36,7 +29,7 @@ Interp_Value :: struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interp_program :: (i: *Interp) {
|
interp_program :: (i: *Vm) {
|
||||||
try_lazy_init(i);
|
try_lazy_init(i);
|
||||||
|
|
||||||
for i.toplevel {
|
for i.toplevel {
|
||||||
|
|
@ -44,7 +37,7 @@ interp_program :: (i: *Interp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interp_statement :: (i: *Interp, stmt: *Node, scope: *Interp_Scope) {
|
interp_statement :: (i: *Vm, stmt: *Node, scope: *Interp_Scope) {
|
||||||
if stmt.kind == {
|
if stmt.kind == {
|
||||||
case .variable;
|
case .variable;
|
||||||
var := stmt.(*Node_Var);
|
var := stmt.(*Node_Var);
|
||||||
|
|
@ -112,7 +105,7 @@ interp_statement :: (i: *Interp, stmt: *Node, scope: *Interp_Scope) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interp_lvalue :: (i: *Interp, expr: *Node, scope: *Interp_Scope) -> *Interp_Value {
|
interp_lvalue :: (i: *Vm, expr: *Node, scope: *Interp_Scope) -> *Interp_Value {
|
||||||
if expr.kind == {
|
if expr.kind == {
|
||||||
case .symbol;
|
case .symbol;
|
||||||
sym := expr.(*Node_Symbol);
|
sym := expr.(*Node_Symbol);
|
||||||
|
|
@ -128,7 +121,7 @@ interp_lvalue :: (i: *Interp, expr: *Node, scope: *Interp_Scope) -> *Interp_Valu
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interp_expression :: (i: *Interp, expr: *Node, scope: *Interp_Scope) -> *Interp_Value {
|
interp_expression :: (i: *Vm, expr: *Node, scope: *Interp_Scope) -> *Interp_Value {
|
||||||
if expr.kind == {
|
if expr.kind == {
|
||||||
case .procedure_call;
|
case .procedure_call;
|
||||||
call := expr.(*Node_Procedure_Call);
|
call := expr.(*Node_Procedure_Call);
|
||||||
|
|
@ -302,13 +295,13 @@ make_scope :: (parent: *Interp_Scope) -> *Interp_Scope {
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
make_interp_value :: (i: *Interp, kind: Interp_Value.Kind) -> *Interp_Value {
|
make_interp_value :: (i: *Vm, kind: Interp_Value.Kind) -> *Interp_Value {
|
||||||
value := mem.request_memory(Interp_Value,, allocator = i.allocator);
|
value := mem.request_memory(Interp_Value,, allocator = i.interp_allocator);
|
||||||
value.kind = kind;
|
value.kind = kind;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
try_lazy_init :: (i: *Interp) {
|
try_lazy_init :: (i: *Vm) {
|
||||||
value_nil = make_interp_value(i, .nil);
|
value_nil = make_interp_value(i, .nil);
|
||||||
|
|
||||||
value_true = make_interp_value(i, .bool);
|
value_true = make_interp_value(i, .bool);
|
||||||
202
x/vm/module.jai
Normal file
202
x/vm/module.jai
Normal file
|
|
@ -0,0 +1,202 @@
|
||||||
|
// #module_parameters(RUN_TESTS := false);
|
||||||
|
|
||||||
|
Vm :: struct {
|
||||||
|
reports: [..]Report;
|
||||||
|
|
||||||
|
parser_allocator: Allocator;
|
||||||
|
toplevel: [..]*Node;
|
||||||
|
previous: Token;
|
||||||
|
filename: string = "(unnamed file)";
|
||||||
|
source: string;
|
||||||
|
offset: int;
|
||||||
|
|
||||||
|
interp_allocator: Allocator;
|
||||||
|
global: *Interp_Scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
#load "parser.jai";
|
||||||
|
#load "resolver.jai";
|
||||||
|
#load "interp.jai";
|
||||||
|
|
||||||
|
#scope_module;
|
||||||
|
|
||||||
|
Report :: struct {
|
||||||
|
message: string;
|
||||||
|
offset: int = -1;
|
||||||
|
error: bool;
|
||||||
|
extras: Extra = .show_entire_line;
|
||||||
|
|
||||||
|
Extra :: enum_flags {
|
||||||
|
hide_location;
|
||||||
|
show_entire_line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
report :: (vm: *Vm, message := "", args: ..Any) -> *Report {
|
||||||
|
r: *Report;
|
||||||
|
|
||||||
|
if vm.reports.count != 0 {
|
||||||
|
last := *vm.reports[vm.reports.count - 1];
|
||||||
|
if last.offset == vm.offset {
|
||||||
|
r = last;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = array.append(*vm.reports);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = array.append(*vm.reports);
|
||||||
|
}
|
||||||
|
|
||||||
|
r.message = basic.tprint(message, ..args);
|
||||||
|
r.offset = vm.offset;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
an_error_was_reported :: (vm: Vm) -> bool {
|
||||||
|
if vm.reports.count == 0 return false;
|
||||||
|
|
||||||
|
reported_error := false;
|
||||||
|
for < vm.reports {
|
||||||
|
if it.error reported_error = true;
|
||||||
|
|
||||||
|
line := -1;
|
||||||
|
column := -1;
|
||||||
|
|
||||||
|
if !(it.extras & .hide_location) {
|
||||||
|
for 0..vm.source.count - 1 {
|
||||||
|
if vm.source[it] == "\n" {
|
||||||
|
line += 1;
|
||||||
|
column = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
column += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
basic.print("%:%,% ", vm.filename, line, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
basic.print("%\n", it.message);
|
||||||
|
|
||||||
|
if it.extras & .show_entire_line {
|
||||||
|
i := it.offset;
|
||||||
|
start := i;
|
||||||
|
while i >= 0 {
|
||||||
|
if vm.source[i] == "\n" {
|
||||||
|
start = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
end := it.offset;
|
||||||
|
|
||||||
|
i = it.offset;
|
||||||
|
while i < vm.source.count {
|
||||||
|
if vm.source[i] == "\n" {
|
||||||
|
end = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
line := string.{ data = vm.source.data + start, count = end - start };
|
||||||
|
basic.print("\t%\n", strings.trim(line));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reported_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// exported to the entire module since we want these everywhere
|
||||||
|
|
||||||
|
mem :: #import "jc/memory";
|
||||||
|
array :: #import "jc/array";
|
||||||
|
kv :: #import "jc/kv";
|
||||||
|
|
||||||
|
basic :: #import "Basic"; // @future
|
||||||
|
strings :: #import "String"; // @future
|
||||||
|
|
||||||
|
#scope_file;
|
||||||
|
|
||||||
|
#run {
|
||||||
|
vm: Vm;
|
||||||
|
|
||||||
|
ok := parse_string(*vm, #string END
|
||||||
|
fn add(l, r) do return l + r end
|
||||||
|
fn sub(l, r) do return l - r end
|
||||||
|
fn mul(l, r) do return l * r end
|
||||||
|
fn div(l, r) do return l / r end
|
||||||
|
|
||||||
|
var x = 21.0
|
||||||
|
var y = 22.0
|
||||||
|
var z = x + y
|
||||||
|
|
||||||
|
x = x + 1.0 / 2.0
|
||||||
|
print x
|
||||||
|
|
||||||
|
x = add(x, div(1.0, 2.0))
|
||||||
|
print x
|
||||||
|
|
||||||
|
print x == x
|
||||||
|
print x == y
|
||||||
|
print x == z
|
||||||
|
|
||||||
|
assert x == y
|
||||||
|
assert x != z
|
||||||
|
|
||||||
|
// def (
|
||||||
|
// Add = poly[T] proc(x T, y T) T do return x + y end
|
||||||
|
// Sub = poly[T] proc(x T, y T) T do return x - y end
|
||||||
|
// Mul = poly[T] proc(x T, y T) T do return x * y end
|
||||||
|
// Div = poly[T] proc(x T, y T) T do return x / y end
|
||||||
|
// )
|
||||||
|
|
||||||
|
// def (
|
||||||
|
// Addi = Add[int]
|
||||||
|
// Addf = Add[float]
|
||||||
|
// Subi = Sub[int]
|
||||||
|
// Subf = Sub[float]
|
||||||
|
// Muli = Mul[int]
|
||||||
|
// Mulf = Mul[float]
|
||||||
|
// Divi = Div[int]
|
||||||
|
// Divf = Div[float]
|
||||||
|
// )
|
||||||
|
|
||||||
|
// def Foo = struct {
|
||||||
|
// x int = 1
|
||||||
|
// y int = 2
|
||||||
|
// z int = 3
|
||||||
|
// }
|
||||||
|
|
||||||
|
// def Value = union {
|
||||||
|
// i int
|
||||||
|
// f float
|
||||||
|
// b bool
|
||||||
|
// }
|
||||||
|
|
||||||
|
// def Kind = enum {
|
||||||
|
// a
|
||||||
|
// b
|
||||||
|
// c
|
||||||
|
// d
|
||||||
|
// }
|
||||||
|
|
||||||
|
// var foo = Foo{ x = 10, y = 20, z = 30 }
|
||||||
|
// var val = Value{ f = 3.14 }
|
||||||
|
// var kind = Kind.a
|
||||||
|
END);
|
||||||
|
|
||||||
|
if an_error_was_reported(vm) return;
|
||||||
|
|
||||||
|
resolve_everything(*vm);
|
||||||
|
// generate_bytecode(*vm);
|
||||||
|
// interp_bytecode(*vm);
|
||||||
|
}
|
||||||
|
|
||||||
|
// #if RUN_TESTS {
|
||||||
|
// test :: #import "jc/test";
|
||||||
|
// }
|
||||||
|
|
@ -296,17 +296,7 @@ Node_Return :: struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser :: struct {
|
parse_string :: (p: *Vm, source: string) -> bool {
|
||||||
allocator: Allocator;
|
|
||||||
toplevel: [..]*Node;
|
|
||||||
|
|
||||||
previous: Token;
|
|
||||||
filename: string;
|
|
||||||
source: string;
|
|
||||||
offset: int;
|
|
||||||
}
|
|
||||||
|
|
||||||
parse_string :: (p: *Parser, source: string) -> bool {
|
|
||||||
try_lazy_init(p);
|
try_lazy_init(p);
|
||||||
|
|
||||||
p.source = source;
|
p.source = source;
|
||||||
|
|
@ -319,7 +309,7 @@ parse_string :: (p: *Parser, source: string) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
node := parse_statement(p);
|
node := parse_statement(p);
|
||||||
if node != null array.append(*p.toplevel, node);
|
if node == null array.append(*p.toplevel, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -328,7 +318,7 @@ parse_string :: (p: *Parser, source: string) -> bool {
|
||||||
|
|
||||||
#scope_file;
|
#scope_file;
|
||||||
|
|
||||||
parse_statement :: (p: *Parser) -> *Node {
|
parse_statement :: (p: *Vm) -> *Node {
|
||||||
t := peek_token(p);
|
t := peek_token(p);
|
||||||
if t.kind == {
|
if t.kind == {
|
||||||
// var sym type_expr
|
// var sym type_expr
|
||||||
|
|
@ -470,9 +460,10 @@ parse_statement :: (p: *Parser) -> *Node {
|
||||||
return parse_simple_statement(p);
|
return parse_simple_statement(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_simple_statement :: (p: *Parser) -> *Node {
|
parse_simple_statement :: (p: *Vm) -> *Node {
|
||||||
dst := parse_expression(p);
|
dst := parse_expression(p);
|
||||||
basic.assert(dst != null, "expected expression for simple statement");
|
if dst == null return null;
|
||||||
|
// basic.assert(dst != null, "expected expression for simple statement");
|
||||||
|
|
||||||
t := peek_token(p);
|
t := peek_token(p);
|
||||||
if t.kind == {
|
if t.kind == {
|
||||||
|
|
@ -519,7 +510,7 @@ parse_simple_statement :: (p: *Parser) -> *Node {
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_block :: (p: *Parser) -> *Node_Block {
|
parse_block :: (p: *Vm) -> *Node_Block {
|
||||||
t, ok := expect_token(p, .kw_do);
|
t, ok := expect_token(p, .kw_do);
|
||||||
basic.assert(ok, "expected 'do' found '%'", t.str); // @errors
|
basic.assert(ok, "expected 'do' found '%'", t.str); // @errors
|
||||||
|
|
||||||
|
|
@ -541,7 +532,7 @@ parse_block :: (p: *Parser) -> *Node_Block {
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_type_expression :: (p: *Parser) -> *Node_Type {
|
parse_type_expression :: (p: *Vm) -> *Node_Type {
|
||||||
t, ok := expect_token(p, .symbol, .star, .l_square);
|
t, ok := expect_token(p, .symbol, .star, .l_square);
|
||||||
basic.assert(ok, "type expression"); // @errors
|
basic.assert(ok, "type expression"); // @errors
|
||||||
|
|
||||||
|
|
@ -594,7 +585,7 @@ parse_type_expression :: (p: *Parser) -> *Node_Type {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_expression :: (p: *Parser, min_precedence := 1) -> *Node {
|
parse_expression :: (p: *Vm, min_precedence := 1) -> *Node {
|
||||||
get_precedence :: inline (t: Token) -> int {
|
get_precedence :: inline (t: Token) -> int {
|
||||||
if t.kind == {
|
if t.kind == {
|
||||||
case .star; #through;
|
case .star; #through;
|
||||||
|
|
@ -620,7 +611,7 @@ parse_expression :: (p: *Parser, min_precedence := 1) -> *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
node := parse_expression_unary(p);
|
node := parse_expression_unary(p);
|
||||||
basic.assert(node != null, "expected expression"); // @errors
|
if node == null return null;
|
||||||
|
|
||||||
while !at_end(p) {
|
while !at_end(p) {
|
||||||
op := peek_token(p);
|
op := peek_token(p);
|
||||||
|
|
@ -644,7 +635,7 @@ parse_expression :: (p: *Parser, min_precedence := 1) -> *Node {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_expression_unary :: (p: *Parser) -> *Node {
|
parse_expression_unary :: (p: *Vm) -> *Node {
|
||||||
op := peek_token(p);
|
op := peek_token(p);
|
||||||
if op.kind == {
|
if op.kind == {
|
||||||
case .plus; #through;
|
case .plus; #through;
|
||||||
|
|
@ -663,10 +654,10 @@ parse_expression_unary :: (p: *Parser) -> *Node {
|
||||||
return parse_expression_postfix(p);
|
return parse_expression_postfix(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_expression_postfix :: (p: *Parser) -> *Node {
|
parse_expression_postfix :: (p: *Vm) -> *Node {
|
||||||
// @TODO
|
// @TODO
|
||||||
base := parse_expression_base(p);
|
base := parse_expression_base(p);
|
||||||
basic.assert(base != null, "expected expression"); // @errors
|
if base == null return null;
|
||||||
|
|
||||||
t := peek_token(p);
|
t := peek_token(p);
|
||||||
if t.kind == {
|
if t.kind == {
|
||||||
|
|
@ -717,9 +708,9 @@ parse_expression_postfix :: (p: *Parser) -> *Node {
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_expression_base :: (p: *Parser) -> *Node {
|
parse_expression_base :: (p: *Vm) -> *Node {
|
||||||
t, ok := expect_token(p, .kw_true, .kw_false, .number, .symbol, .l_paren);
|
t, ok := expect_token(p, .kw_true, .kw_false, .number, .symbol, .l_paren);
|
||||||
basic.assert(ok, "expected expression, found '%'", t.str); // @errors
|
if !ok return null;
|
||||||
|
|
||||||
if t.kind == {
|
if t.kind == {
|
||||||
case .kw_true; #through;
|
case .kw_true; #through;
|
||||||
|
|
@ -742,7 +733,10 @@ parse_expression_base :: (p: *Parser) -> *Node {
|
||||||
node.value_kind = .float;
|
node.value_kind = .float;
|
||||||
|
|
||||||
value, ok := strings.parse_float(*copy);
|
value, ok := strings.parse_float(*copy);
|
||||||
basic.assert(ok, "malformed float '%'", t.str); // @errors
|
if !ok {
|
||||||
|
report(p, "malformed float '%'", t.str); // @location
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
node.f = value;
|
node.f = value;
|
||||||
}
|
}
|
||||||
|
|
@ -753,7 +747,10 @@ parse_expression_base :: (p: *Parser) -> *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
value, ok := strings.parse_int(*copy);
|
value, ok := strings.parse_int(*copy);
|
||||||
basic.assert(ok, "malformed integer '%'", t.str); // @errors
|
if !ok {
|
||||||
|
report(p, "malformed integer '%'", t.str); // @location
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
node.i = value;
|
node.i = value;
|
||||||
}
|
}
|
||||||
|
|
@ -762,10 +759,16 @@ parse_expression_base :: (p: *Parser) -> *Node {
|
||||||
|
|
||||||
case .l_paren;
|
case .l_paren;
|
||||||
node := parse_expression(p);
|
node := parse_expression(p);
|
||||||
basic.assert(node != null, "expected expression"); // @errors
|
if node == null {
|
||||||
|
report(p, "expected an expression after '('");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
_, ok := expect_token(p, .r_paren);
|
t, ok := expect_token(p, .r_paren);
|
||||||
basic.assert(ok, "expected ')'"); // @errors
|
if !ok {
|
||||||
|
report(p, "expected ')', found '%'", t.str); // @errors
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
@ -773,29 +776,29 @@ parse_expression_base :: (p: *Parser) -> *Node {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
make_node :: (p: *Parser, $T: Type) -> *T {
|
make_node :: (p: *Vm, $T: Type) -> *T {
|
||||||
node := mem.request_memory(T,, allocator = p.allocator);
|
node := mem.request_memory(T,, allocator = p.parser_allocator);
|
||||||
|
|
||||||
#if #exists(T.init) {
|
#if #exists(T.init) {
|
||||||
T.init(node, p.allocator);
|
T.init(node, p.parser_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
make_node :: (p: *Parser, $type_kind: Node_Type.Type_Kind) -> *Node_Type {
|
make_node :: (p: *Vm, $type_kind: Node_Type.Type_Kind) -> *Node_Type {
|
||||||
type := mem.request_memory(Node_Type,, allocator = p.allocator);
|
type := mem.request_memory(Node_Type,, allocator = p.parser_allocator);
|
||||||
type.type_kind = type_kind;
|
type.type_kind = type_kind;
|
||||||
Node_Type.init(type, p.allocator);
|
Node_Type.init(type, p.parser_allocator);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
peek_token :: (p: *Parser) -> Token {
|
peek_token :: (p: *Vm) -> Token {
|
||||||
copy := p.*;
|
copy := p.*;
|
||||||
return consume_token(*copy);
|
return consume_token(*copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
at_end :: (p: *Parser) -> bool {
|
at_end :: (p: *Vm) -> bool {
|
||||||
return p.offset >= p.source.count;
|
return p.offset >= p.source.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -815,8 +818,10 @@ continues_number :: (c: u8) -> bool {
|
||||||
return starts_number(c) || c == ".";
|
return starts_number(c) || c == ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
consume_token :: (p: *Parser) -> Token {
|
consume_token :: (p: *Vm) -> Token {
|
||||||
if at_end(p) return .{ kind = .end_of_file };
|
if at_end(p) {
|
||||||
|
return .{ kind = .end_of_file };
|
||||||
|
}
|
||||||
|
|
||||||
c := p.source[p.offset];
|
c := p.source[p.offset];
|
||||||
|
|
||||||
|
|
@ -947,7 +952,7 @@ consume_token :: (p: *Parser) -> Token {
|
||||||
return .{ kind = .invalid, str = s };
|
return .{ kind = .invalid, str = s };
|
||||||
}
|
}
|
||||||
|
|
||||||
expect_token :: (p: *Parser, kinds: ..Token.Kind) -> Token, bool {
|
expect_token :: (p: *Vm, kinds: ..Token.Kind) -> Token, bool {
|
||||||
t := consume_token(p);
|
t := consume_token(p);
|
||||||
for kinds if it == t.kind {
|
for kinds if it == t.kind {
|
||||||
return t, true;
|
return t, true;
|
||||||
|
|
@ -956,7 +961,7 @@ expect_token :: (p: *Parser, kinds: ..Token.Kind) -> Token, bool {
|
||||||
return t, false;
|
return t, false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try_lazy_init :: (p: *Parser) {
|
try_lazy_init :: (p: *Vm) {
|
||||||
mem.lazy_set_allocator(p);
|
mem.lazy_set_allocator(*p.toplevel, p.parser_allocator);
|
||||||
mem.lazy_set_allocator(*p.toplevel);
|
mem.lazy_set_allocator(*p.reports, p.parser_allocator);
|
||||||
}
|
}
|
||||||
2
x/vm/resolver.jai
Normal file
2
x/vm/resolver.jai
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
resolve_everything :: (vm: *Vm) {
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue