Skip to content

Commit b9e4a1a

Browse files
committed
parse +Expression (for generate boxed values)
1 parent a1c03aa commit b9e4a1a

File tree

6 files changed

+97
-73
lines changed

6 files changed

+97
-73
lines changed

lib/rivet/src/checker/exprs.ri

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,9 @@ extend Checker {
588588
unary.pos
589589
);
590590
},
591+
.Plus -> if unary.type is .Basic(basic_t) {
592+
unary.type = .Basic(basic_t.sym, is_boxed: true, is_mut: unary.is_mut_ptr, pos: basic_t.pos);
593+
},
591594
.Amp -> {
592595
mut expected_pointer := false;
593596
mut indexable_pointer := false;

lib/rivet/src/parser/exprs.ri

Lines changed: 70 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -313,78 +313,84 @@ extend Parser {
313313
}
314314
},
315315
self.tok.kind in [.Lbracket, .Plus] -> {
316-
mut is_dyn := self.accept(.Plus);
317-
mut elems := []mut ast.Expr();
318316
mut pos := self.tok.pos;
319-
self.next();
320-
if self.tok.kind != .Rbracket {
321-
while {
322-
elems.push(self.parse_expr());
323-
if !self.accept(.Comma) {
324-
break;
325-
}
326-
}
327-
}
328-
self.expect(.Rbracket);
329-
pos += self.prev_tok.pos;
330-
if !is_dyn && (elems.len == 0 || elems.len == 1 && self.tok.kind !in [
331-
.Semicolon, .Comma, .Rbrace, .Rparen
332-
]) {
333-
// []T() or [SIZE]T()
334-
is_dyn = elems.len == 0;
317+
mut is_dyn := self.accept(.Plus);
318+
if self.tok.kind != .Lbracket {
335319
is_mut := self.accept(.KwMut);
336-
elem_type := self.parse_type();
337-
mut init_value: ?ast.Expr := none;
338-
mut cap_value: ?ast.Expr := none;
339-
mut len_value: ?ast.Expr := none;
340-
self.expect(.Lparen);
341-
while self.tok.kind != .Rparen {
342-
mut arg_pos := self.tok.pos;
343-
arg_name := self.parse_name();
344-
self.expect(.Colon);
345-
arg_value := self.parse_expr();
346-
arg_pos += self.prev_tok.pos;
347-
match arg_name {
348-
"init" -> if init_value == none {
349-
init_value = arg_value;
350-
} else {
351-
report.error("duplicate array constructor argument `init`", arg_pos);
352-
break;
353-
},
354-
"len" if is_dyn -> if len_value == none {
355-
len_value = arg_value;
356-
} else {
357-
report.error("duplicate array constructor argument `len`", arg_pos);
358-
break;
359-
},
360-
"cap" if is_dyn -> if cap_value == none {
361-
cap_value = arg_value;
362-
} else {
363-
report.error("duplicate array constructor argument `cap`", arg_pos);
364-
break;
365-
},
366-
else -> {
367-
report.error(
368-
"unknown array constructor argument `{}`".fmt(arg_name),
369-
arg_pos
370-
);
320+
right := self.parse_expr();
321+
.Unary(right, .Plus, is_mut, pos + right.position())
322+
} else {
323+
mut elems := []mut ast.Expr();
324+
self.next();
325+
if self.tok.kind != .Rbracket {
326+
while {
327+
elems.push(self.parse_expr());
328+
if !self.accept(.Comma) {
371329
break;
372330
}
373331
}
374-
if self.tok.kind != .Rparen {
375-
self.expect(.Comma);
376-
}
377332
}
378-
self.expect(.Rparen);
333+
self.expect(.Rbracket);
379334
pos += self.prev_tok.pos;
380-
if !is_dyn {
381-
len_value = elems[0];
335+
if !is_dyn && (elems.len == 0 || elems.len == 1 && self.tok.kind !in [
336+
.Semicolon, .Comma, .Rbrace, .Rparen
337+
]) {
338+
// []T() or [SIZE]T()
339+
is_dyn = elems.len == 0;
340+
is_mut := self.accept(.KwMut);
341+
elem_type := self.parse_type();
342+
mut init_value: ?ast.Expr := none;
343+
mut cap_value: ?ast.Expr := none;
344+
mut len_value: ?ast.Expr := none;
345+
self.expect(.Lparen);
346+
while self.tok.kind != .Rparen {
347+
mut arg_pos := self.tok.pos;
348+
arg_name := self.parse_name();
349+
self.expect(.Colon);
350+
arg_value := self.parse_expr();
351+
arg_pos += self.prev_tok.pos;
352+
match arg_name {
353+
"init" -> if init_value == none {
354+
init_value = arg_value;
355+
} else {
356+
report.error("duplicate array constructor argument `init`", arg_pos);
357+
break;
358+
},
359+
"len" if is_dyn -> if len_value == none {
360+
len_value = arg_value;
361+
} else {
362+
report.error("duplicate array constructor argument `len`", arg_pos);
363+
break;
364+
},
365+
"cap" if is_dyn -> if cap_value == none {
366+
cap_value = arg_value;
367+
} else {
368+
report.error("duplicate array constructor argument `cap`", arg_pos);
369+
break;
370+
},
371+
else -> {
372+
report.error(
373+
"unknown array constructor argument `{}`".fmt(arg_name),
374+
arg_pos
375+
);
376+
break;
377+
}
378+
}
379+
if self.tok.kind != .Rparen {
380+
self.expect(.Comma);
381+
}
382+
}
383+
self.expect(.Rparen);
384+
pos += self.prev_tok.pos;
385+
if !is_dyn {
386+
len_value = elems[0];
387+
}
388+
.ArrayCtor(
389+
is_dyn, is_mut, elem_type, init_value, cap_value, len_value, pos: pos
390+
)
391+
} else {
392+
.ArrayLiteral(elems, is_dyn, pos)
382393
}
383-
.ArrayCtor(
384-
is_dyn, is_mut, elem_type, init_value, cap_value, len_value, pos: pos
385-
)
386-
} else {
387-
.ArrayLiteral(elems, is_dyn, pos)
388394
}
389395
},
390396
self.tok.kind == .Name -> if self.peek_tok.kind == .Char {

rivetc/src/checker.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,9 @@ def check_expr(self, expr):
608608
"operator `-` can only be used with signed values",
609609
expr.pos
610610
)
611+
elif expr.op == Kind.Plus:
612+
if isinstance(expr.typ, type.Type):
613+
expr.typ = type.Type(expr.typ.sym, True, expr.is_mut_ptr)
611614
elif expr.op == Kind.Amp:
612615
if isinstance(self.expected_type, type.Ptr):
613616
expected_pointer = True

rivetc/src/codegen/__init__.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,10 @@ def gen_expr(self, expr, custom_tmp = None):
17381738
return ir.Ident(expr_typ_ir, tmp)
17391739
elif isinstance(expr, ast.UnaryExpr):
17401740
right = self.gen_expr_with_cast(expr.right_typ, expr.right)
1741+
if expr.op == Kind.Plus:
1742+
res = self.boxed_instance(cg_utils.mangle_symbol(expr.right_typ.symbol()))
1743+
self.cur_func.store_ptr(res, ir.Inst(ir.InstKind.Cast, [right, right.typ]))
1744+
return res
17411745
if expr.op == Kind.Amp:
17421746
tmp = self.cur_func.local_name()
17431747
if isinstance(
@@ -2689,8 +2693,8 @@ def boxed_instance(self, name, custom_name = None):
26892693
)
26902694
inst = ir.Inst(
26912695
ir.InstKind.Call,
2692-
[ir.Name("_R4core3mem9raw_allocF"),
2693-
ir.Name(f"sizeof({name})")]
2696+
[ir.Name("_R4core3mem11boxed_allocF"),
2697+
ir.Name(f"sizeof({name})"), ir.Name("NULL")]
26942698
)
26952699
if custom_name:
26962700
self.cur_func.store(tmp, inst)
@@ -2977,7 +2981,7 @@ def ir_type(self, typ, gen_self_arg = False):
29772981
return ir.UINT_T
29782982
return ir.Type(typ_sym.name)
29792983
res = ir.Type(cg_utils.mangle_symbol(typ_sym))
2980-
if typ_sym.is_boxed():
2984+
if typ_sym.is_boxed() or (isinstance(typ, type.Type) and typ.is_boxed):
29812985
return res.ptr(True)
29822986
return res
29832987

rivetc/src/parser.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1009,9 +1009,12 @@ def parse_primary_expr(self):
10091009
elif self.tok.kind in (Kind.KwUnsafe, Kind.Lbrace):
10101010
expr = self.parse_block_expr()
10111011
elif self.tok.kind in (Kind.Lbracket, Kind.Plus):
1012+
pos = self.tok.pos
10121013
is_dyn = self.accept(Kind.Plus)
1014+
if self.tok.kind != Kind.Lbracket:
1015+
is_mut = self.accept(Kind.KwMut)
1016+
return ast.UnaryExpr(self.parse_expr(), Kind.Plus, is_mut, pos)
10131017
elems = []
1014-
pos = self.tok.pos
10151018
self.next()
10161019
if self.tok.kind != Kind.Rbracket:
10171020
while True:

rivetc/src/resolver.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,6 @@ def resolve_type(self, typ):
485485
return True
486486
elif isinstance(typ, type.Ptr):
487487
return self.resolve_type(typ.typ)
488-
elif isinstance(typ, type.Ptr):
489-
return self.resolve_type(typ.typ)
490488
elif isinstance(typ, type.Variadic):
491489
if self.resolve_type(typ.typ):
492490
elem_sym = typ.typ.symbol()
@@ -550,6 +548,7 @@ def resolve_type(self, typ):
550548
elif isinstance(typ, type.Type):
551549
if typ.is_resolved():
552550
return True # resolved
551+
result = False
553552
if isinstance(typ.expr, ast.Ident):
554553
self.resolve_ident(typ.expr)
555554
if typ.expr.sym != None:
@@ -560,7 +559,7 @@ def resolve_type(self, typ):
560559
if self.resolve_type(typ.expr.sym.info.parent):
561560
typ.unalias()
562561
typ_sym = typ.symbol()
563-
return True
562+
result = True
564563
else:
565564
report.error(
566565
f"expected type, found {typ.expr.sym.typeof()}",
@@ -587,7 +586,7 @@ def resolve_type(self, typ):
587586
typ.expr.field_sym.info.parent
588587
):
589588
typ.unalias()
590-
return True
589+
result = True
591590
else:
592591
report.error(
593592
f"expected type, found {typ.expr.field_sym.typeof()}",
@@ -596,11 +595,17 @@ def resolve_type(self, typ):
596595
elif isinstance(typ.expr, ast.SelfTyExpr):
597596
if self.self_sym:
598597
typ.resolve(self.self_sym)
599-
return True
598+
result = True
600599
else:
601600
report.error("cannot resolve type for `Self`", typ.expr.pos)
602601
else:
603602
report.error(f"expected type, found {typ.expr}", typ.expr.pos)
603+
if result and isinstance(typ, type.Type) and not typ.is_boxed:
604+
tsym = typ.symbol()
605+
#if isinstance(tsym, sym.Type) and tsym.kind != sym.TypeKind.Trait and tsym.is_boxed():
606+
# report.warn(f"cannot use type `{tsym.name}` as a simple value", typ.expr.pos)
607+
# report.help(f"type `{tsym.name}` is boxed, you should use `+{typ.expr}` instead")
608+
return result
604609
return False
605610

606611
def eval_size(self, expr):

0 commit comments

Comments
 (0)