aboutsummaryrefslogtreecommitdiff
path: root/src/parse.cff
diff options
context:
space:
mode:
Diffstat (limited to 'src/parse.cff')
-rw-r--r--src/parse.cff34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/parse.cff b/src/parse.cff
index 85d9de5..0eb251d 100644
--- a/src/parse.cff
+++ b/src/parse.cff
@@ -756,7 +756,6 @@ fn parseagg(P *Parser, loc Loc, kind AggKind, name *const u8, retdecl **Decl) *c
size = kind == :Struct ? off + type.size
: MAX(size, type.size);
}
- efmt("%s\t %s\t off %z\n", agg.name ?? "?", name, off);
flds->push({ name, type, off });
if !lexmatch(P, #null, ',') {
@@ -1666,10 +1665,10 @@ fn pexpostfix(P *Parser) Expr {
case lexmatch(P, &tok, '->');
let name = (tok = lexexpects(P, :ident, "method name")).u.ident;
let ty = ex.ty;
- if ty->is(:Ptr) {
+ let exptr = #f;
+ if (exptr = ty->is(:Ptr)) {
ty = ty.u.Ptr;
}
- ty = unconstify(ty);
if !ty->is(:Agg) {
fatal(P, tok.loc, "left-hand-side is not an aggregate (%t)", ty);
}
@@ -1685,7 +1684,36 @@ fn pexpostfix(P *Parser) Expr {
if Fn.params.#len == 0 {
fatal(P, tok.loc, "function takes no arguments");
}
+
let args Vec<Expr> = {};
+ let recv0 = Fn.params[0], recv = recv0;
+ let metptr = #f;
+ if (metptr = recv->is(:Ptr)) {
+ recv = recv.u.Ptr;
+ }
+ if unconstify(ty) != unconstify(recv) {
+ err(P, tok.loc, "method receiver type mismatch for `->%s' (%t, expected %t)",
+ name, ty, recv0);
+ }
+ switch {
+ case !exptr and !metptr;
+
+ case exptr and !metptr;
+ ex = { ex.loc, ty, :UnOp{:deref, exprdup(P.alloc, ex)}};
+
+ case !exptr and metptr;
+ if !islvalue(ex) {
+ err(P, tok.loc, "cannot call `->%s' by reference, lhs is not an lvalue", name);
+ } else if ty.konst and !recv.konst {
+ err(P, tok.loc, "constness mismatch: method takes %t but got %t", recv0, ex.ty);
+ }
+ ex = { ex.loc, mkptrtype(ty), :UnOp{:addrof, exprdup(P.alloc, ex)}};
+
+ case exptr and metptr;
+ if ty.konst and !recv.konst {
+ err(P, tok.loc, "constness mismatch: method takes %t but got %t", recv0, ex.ty);
+ }
+ }
args->push(ex);
let param = &Fn.params[1];
while !lexmatch(P, #null, ')') {