aboutsummaryrefslogtreecommitdiff
path: root/src/cffc.hff
diff options
context:
space:
mode:
Diffstat (limited to 'src/cffc.hff')
-rw-r--r--src/cffc.hff31
1 files changed, 27 insertions, 4 deletions
diff --git a/src/cffc.hff b/src/cffc.hff
index e329965..11adba6 100644
--- a/src/cffc.hff
+++ b/src/cffc.hff
@@ -41,7 +41,7 @@ enum TokT : i32 {
typearg,
eof,
}
-def NUM_KEYWORDS int = TokT:NUM_KEYWORDS;
+def NUM_KEYWORDS = as(int)TokT:NUM_KEYWORDS;
struct Tok {
t TokT,
@@ -89,9 +89,9 @@ struct Type {
Bool,
Int struct { sgn bool },
Flo,
- Ptr *Type,
+ Ptr *const Type,
Arr struct { child *const Type, length i64 },
- Slice *Type,
+ Slice *const Type,
Fn struct {
params [#]*const Type,
variadic bool,
@@ -204,11 +204,14 @@ struct Expr {
EUnionIni struct { var *const AggField, ex *Expr },
AggIni struct { flds [#]*const AggField, exs [#]Expr },
ArrIni struct { idxs [#]u32, exs [#]Expr, maxn i64 },
+ VaStart *Expr,
+ VaArg *Expr,
+ VaCopy struct { dst *Expr, src *Expr },
+ VaEnd *Expr,
Stmt Block,
}
}
-
struct Defers {
next *Defers,
blockid int,
@@ -333,6 +336,26 @@ struct Decl {
myenv *Env,
}
+fn islvalue(ex *Expr) bool {
+ switch ex.u {
+ case Symbol decl;
+ return decl.u.#tag == :Let or decl.u.#tag == :Static;
+ case UnOp u;
+ return u.op == :deref;
+ case Index idx;
+ return idx.lhs.ty->is(:Ptr) or islvalue(idx.lhs);
+ case Dot dot;
+ return dot.lhs.ty->is(:Ptr) or islvalue(dot.lhs);
+ case BitDot bdot;
+ return bdot.lhs.ty->is(:Ptr) or islvalue(bdot.lhs);
+ case BitRaw ex;
+ return ex.ty->is(:Ptr) or islvalue(ex);
+ case EUTag;
+ return #t;
+ }
+ return #f;
+}
+
def ATTR_LAX = 1u32;
struct ExpanArg {