stage0 新增内存复制指令 重构vm交互
This commit is contained in:
1 parent
0b8f649818
commit
40cffa9cb5
22 files changed
+626
-158
No files matched your search
+66
-23
@@ -460,9 +460,8 @@ fn parse_pattern_atom(self: *Parser): usize {
|
||||
var sub = parse_pattern(self);
|
||||
var pn = Ast.node(self.ast, ref);
|
||||
match pn.body {
|
||||
.PatternDot(pd) => {
|
||||
.PatternDot(&pd) => {
|
||||
pd.sub_pattern = sub;
|
||||
pn.body = .PatternDot(pd);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
@@ -508,6 +507,24 @@ fn parse_pattern_atom(self: *Parser): usize {
|
||||
}
|
||||
ret ref;
|
||||
},
|
||||
.And => {
|
||||
// `&name`:解包左值引用绑定。仅允许作用于绑定名。
|
||||
advance(self);
|
||||
var nx = peek(self);
|
||||
if nx == null {
|
||||
parse_error(self, nx, "expected binding name after '&'");
|
||||
ret 0;
|
||||
}
|
||||
match nx.kind {
|
||||
.Ident => {},
|
||||
_ => {
|
||||
parse_error(self, nx, "expected binding name after '&'");
|
||||
ret 0;
|
||||
},
|
||||
}
|
||||
var inner = parse_pattern_atom(self);
|
||||
ret new_node(self, .PatternRef(.{ .pat = inner }), t);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
@@ -547,7 +564,7 @@ fn parse_pattern(self: *Parser): usize {
|
||||
|
||||
// ---- 声明 ----
|
||||
|
||||
fn parse_tag_list(self: *Parser, out: *Vec, is_external: bool, allow_at: bool) {
|
||||
fn parse_tag_list(self: *Parser, out: *Vec, is_external: bool, allow_at: bool, bang_only: bool) {
|
||||
while !self.failed {
|
||||
var t = peek(self);
|
||||
if t == null { ret; }
|
||||
@@ -556,14 +573,21 @@ fn parse_tag_list(self: *Parser, out: *Vec, is_external: bool, allow_at: bool) {
|
||||
else if kind_is_punct(t.kind, .Sharp) { is_at = false; }
|
||||
else { ret; }
|
||||
if !allow_at && is_at { ret; }
|
||||
advance(self);
|
||||
if is_external {
|
||||
t = peek(self);
|
||||
if t == null || !kind_is_punct(t.kind, .Not) {
|
||||
parse_error(self, t, "expected '!' in external tag");
|
||||
ret;
|
||||
}
|
||||
if bang_only {
|
||||
// 仅消费 `#!`/`@!` 形式的当前层 tag;遇到普通 `#name` 即停。
|
||||
var save = self.pos;
|
||||
advance(self);
|
||||
var nt = peek(self);
|
||||
var has_bang = nt != null && kind_is_punct(nt.kind, .Not);
|
||||
self.pos = save;
|
||||
if !has_bang { ret; }
|
||||
}
|
||||
advance(self);
|
||||
t = peek(self);
|
||||
var ext_here = is_external;
|
||||
if t != null && kind_is_punct(t.kind, .Not) {
|
||||
advance(self);
|
||||
ext_here = true;
|
||||
}
|
||||
t = peek(self);
|
||||
if t == null { ret; }
|
||||
@@ -572,14 +596,14 @@ fn parse_tag_list(self: *Parser, out: *Vec, is_external: bool, allow_at: bool) {
|
||||
// stage1 先分配 tag 节点,再解析参数。
|
||||
var body: Body = .TagItem(.{
|
||||
.is_at = is_at,
|
||||
.is_external = is_external,
|
||||
.is_external = ext_here,
|
||||
.name = t.text,
|
||||
.args = ref_vec(),
|
||||
});
|
||||
if is_external {
|
||||
if ext_here {
|
||||
body = .ExternalTagItem(.{
|
||||
.is_at = is_at,
|
||||
.is_external = is_external,
|
||||
.is_external = ext_here,
|
||||
.name = t.text,
|
||||
.args = ref_vec(),
|
||||
});
|
||||
@@ -608,7 +632,13 @@ fn parse_tag_list(self: *Parser, out: *Vec, is_external: bool, allow_at: bool) {
|
||||
|
||||
fn parse_param_decl_impl(self: *Parser): usize {
|
||||
var attrs = ref_vec();
|
||||
parse_tag_list(self, &attrs, false, true);
|
||||
var is_comptime = false;
|
||||
var c0 = peek(self);
|
||||
if c0 != null && kind_is_keyword(c0.kind, .Comptime) {
|
||||
advance(self);
|
||||
is_comptime = true;
|
||||
}
|
||||
parse_tag_list(self, &attrs, false, true, false);
|
||||
var name = peek(self);
|
||||
if name == null { ret 0; }
|
||||
var ok = false;
|
||||
@@ -620,10 +650,10 @@ fn parse_param_decl_impl(self: *Parser): usize {
|
||||
if !ok { ret 0; }
|
||||
advance(self);
|
||||
if !expect_punct(self, .Colon, "':' in parameter declaration") { ret 0; }
|
||||
parse_tag_list(self, &attrs, false, false);
|
||||
parse_tag_list(self, &attrs, false, false, false);
|
||||
var ty = parse_type_expr(self);
|
||||
ret new_node(self,
|
||||
.ParamDecl(.{ .attr_list = attrs, .name = name.text, .type_expr = ty }),
|
||||
.ParamDecl(.{ .attr_list = attrs, .is_comptime = is_comptime, .name = name.text, .type_expr = ty }),
|
||||
name);
|
||||
}
|
||||
|
||||
@@ -651,11 +681,24 @@ fn parse_param_list(self: *Parser): Vec {
|
||||
if at_punct(self, .Comma) { advance(self); continue; }
|
||||
break;
|
||||
},
|
||||
.Keyword(k) => {
|
||||
if @enum2int(k) == @enum2int(Keyword.Comptime) {
|
||||
var pd2 = parse_param_decl_impl(self);
|
||||
if pd2 != 0 {
|
||||
match Vec.push(&out, &pd2 as *u8) { .Ok => {}, .Err(e) => { ret out; } }
|
||||
}
|
||||
if at_punct(self, .Comma) { advance(self); continue; }
|
||||
break;
|
||||
}
|
||||
parse_error(self, t, "unexpected token in parameter list");
|
||||
break;
|
||||
},
|
||||
.Punct(p) => {
|
||||
if @enum2int(p) == @enum2int(Punct.Ellipsis) {
|
||||
advance(self);
|
||||
var pd = new_node(self, .ParamDecl(.{
|
||||
.attr_list = ref_vec(),
|
||||
.is_comptime = false,
|
||||
.name = ByteView.empty(),
|
||||
.type_expr = 0,
|
||||
}), t);
|
||||
@@ -825,7 +868,7 @@ fn parse_member_decl(self: *Parser, tags: Vec): usize {
|
||||
var t = peek(self);
|
||||
if t != null && kind_is_punct(t.kind, .Colon) {
|
||||
advance(self);
|
||||
parse_tag_list(self, &tags, false, false);
|
||||
parse_tag_list(self, &tags, false, false, false);
|
||||
te = parse_type_expr(self);
|
||||
t = peek(self);
|
||||
if t != null && kind_is_punct(t.kind, .Assign) {
|
||||
@@ -864,7 +907,7 @@ fn parse_comptime_decl(self: *Parser): usize {
|
||||
|
||||
fn parse_container_declaration(self: *Parser): usize {
|
||||
var tags = ref_vec();
|
||||
parse_tag_list(self, &tags, false, false);
|
||||
parse_tag_list(self, &tags, false, false, false);
|
||||
var t = peek(self);
|
||||
if t == null { ret 0; }
|
||||
match t.kind {
|
||||
@@ -1282,9 +1325,9 @@ fn parse_prefix(self: *Parser): usize {
|
||||
if ref == 0 { ret 0; }
|
||||
var n = Ast.node(self.ast, ref);
|
||||
match n.body {
|
||||
.ExprWhile(w) => { w.label = label; n.body = .ExprWhile(w); },
|
||||
.ExprLoop(l) => { l.label = label; n.body = .ExprLoop(l); },
|
||||
.ExprFor(f) => { f.label = label; n.body = .ExprFor(f); },
|
||||
.ExprWhile(&w) => { w.label = label; },
|
||||
.ExprLoop(&l) => { l.label = label; },
|
||||
.ExprFor(&f) => { f.label = label; },
|
||||
_ => {},
|
||||
}
|
||||
ret ref;
|
||||
@@ -2021,7 +2064,7 @@ fn parse_statement(self: *Parser): usize {
|
||||
@enum2int(k) == @enum2int(Keyword.Const) ||
|
||||
@enum2int(k) == @enum2int(Keyword.Type) {
|
||||
var tags = ref_vec();
|
||||
parse_tag_list(self, &tags, false, false);
|
||||
parse_tag_list(self, &tags, false, false, false);
|
||||
var decl: usize = 0;
|
||||
if @enum2int(k) == @enum2int(Keyword.Var) {
|
||||
decl = parse_var_const_decl(self, tags, false);
|
||||
@@ -2188,7 +2231,7 @@ fn parse(self: *Parser) {
|
||||
var t2 = peek(self);
|
||||
self.pos = save;
|
||||
if t2 != null && kind_is_punct(t2.kind, .Not) {
|
||||
parse_tag_list(self, &external_tags, true, true);
|
||||
parse_tag_list(self, &external_tags, true, true, true);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user