typedef struct PStmnt PStmnt; typedef PStmnt *AST; typedef enum { PExprIntLit, // 17 PExprStrLit, // "17" PExprAssign, // x=y PExprModAssign, // x op= y, for op in +-*/%«»&^| PExprMemberget, // x.y // -> is forthcoming PExprIndex, // x[y] PExprId, // x PExprRef, // &x PExprLabelRef, // &&x PExprMonad, // op x, for op in *+-!~ PExprDyad, // x op y, for op in +-*/%«»&^| PExprLogDyad, // x op y, for op in || && PExprCmp, // x op y, for op in < <= == >= > != PExprTernaryIf, // x ? y : z PExprFnCall, // f(x) PExprPreInc, // ++x PExprPreDec, // --x PExprPostInc, // x++ PExprPostDec, // x-- PExprStmnt, /* ({statements;expr;}) * actually statement expression */ } PExprType; typedef enum { PLogDyadOr, PLogDyadAnd, } PLogDyad; typedef enum { PCmpLt, PCmpLe, PCmpEq, PCmpGe, PCmpGt, PCmpNe, } PCmp; typedef enum { PMonadDeref, PMonadPlus, // identity; ignore PMonadNeg, PMonadLogNot, PMonadBitNot, } PMonad; typedef enum { PDyadAdd, PDyadSub, PDyadMul, PDyadDiv, PDyadMod, PDyadLShift, PDyadRShift, PDyadBitAnd, PDyadBitXor, PDyadBitOr, } PDyad; typedef struct PExpr PExpr; struct PExpr { Pos pos; PExprType type; union { s8 int_lit; Cc1 *id; Cc1 *str_lit; struct { PDyad op; PExpr *lhs, *rhs; } dyad; // reused by assign, modassign struct { PLogDyad op; PExpr *lhs, *rhs; } ldyad; struct { PCmp cmp; PExpr *lhs, *rhs; } cmp; struct { PExpr *c, *t, *f; } ternary; //todo : pos struct { PExpr *fn; PExpr *params; } call; struct { PMonad op; PExpr *operand; //generic for monadic operator application } monad; AST stmnt_expr; struct { PExpr *structure; Cc1 *membername; } memberget; struct { PExpr *array, *subscript; } index; }; }; /// 'Forest': collection of syntax trees typedef struct { PStmnt *ast; // (t)ype environment struct { Cc1 **map; usz *stack; } tenv; } Forest; typedef enum { PStmntFnProto, // int f(int); / also uses the 'fn' member, but with unspecified contents for 'body' PStmntFnDecl, // int f(int v) { ... } PStmntVDecl, // int x,y=x; PStmntRet, // return x PStmntExpr, // expr; / actually expression statement PStmntGoto, // goto x PStmntCompound,// {x;y;} PStmntIf, // if(x)y; PStmntIfElse, // if(x)y;else z; PStmntWhile, // while(x)y; PStmntDoWhile, // do x;while(y); PStmntFor, // for(x;y;z)w; PStmntSwitch, // switch(x)y; PStmntTypedef, // typedef int x, y; // reuses vdecl member PStmntContinue,// self-explanatory PStmntBreak, // break; PStmntEmpty, // ; } PStmntType; struct PStmnt { Pos pos; PStmntType type; struct { Cc1 *name; Pos pos; } *labels; struct { PExpr expr; // for 'default', the position here will be valid bool isdefault; } *switch_labels; union { struct { Cc1 *name; PTypeId ret; PTypeSig sig; AST body; } fn; struct { StorageClass storage_class; struct { PTypeId type; Pos tpos; // T pose! Cc1 *name; //Pos npos; Pos eqpos; bool is_init; PExpr init; } *decls; } vdecl; AST compound; PExpr expr; struct { PExpr cond; PStmnt *branch; } sif; struct { PExpr cond; PStmnt *body; } sbody; struct { PExpr cond; PStmnt *branch1, *branch2; } sifelse; struct { PExpr cond; PStmnt *body; } swhile; //while and do-while struct { PStmnt *init; PExpr *cond, *post; //all these can be null if not present PStmnt *body; } sfor; struct { PExpr control; PStmnt *body; } sswitch; }; }; bool parse(TokenList *tl, Forest *out);