compiler

Unnamed Compiled Systems Language Project
git clone http://frotz.net/git/compiler.git
Log | Files | Refs

commit 9078d86940333b9a465eaa36dc700d7164bf5971
parent 1e300fe643d6e540870c5c021c8544a623e03f36
Author: Brian Swetland <swetland@frotz.net>
Date:   Mon,  9 Mar 2020 01:51:02 -0700

compiler: cleanup

- reorganize token encodings
- generic enums for rel/add/mul ops (parse/gen abstraction)
- table driven transforms for ops to ins or ccs
- generate "comparison" items for relops
  - these will lazily resolve to bool, cc, branch, etc
- improve unary op codegen

Diffstat:
Msrc/compiler.c | 157++++++++++++++++++++++++++++++++++++++++++-------------------------------------
1 file changed, 83 insertions(+), 74 deletions(-)

diff --git a/src/compiler.c b/src/compiler.c @@ -19,6 +19,7 @@ typedef uint32_t u32; typedef int32_t i32; +typedef uint8_t u8; // token classes (tok >> 8) enum { @@ -27,31 +28,45 @@ enum { typedef enum { tEOF = 0x000, tEOL = 0x001, - tDOT = 0x002, tCOMMA = 0x003, tCOLON = 0x004, tSEMI = 0x005, tBANG = 0x006, - tOBRACK = 0x007, tCBRACK = 0x008, tOPAREN = 0x009, tCPAREN = 0x00A, - tOBRACE = 0x00B, tCBRACE = 0x00C, tASSIGN = 0x00D, - tPLUS = 0x20E, tMINUS = 0x20F, tSTAR = 0x310, tSLASH = 0x311, - tPERCENT = 0x312, tAMP = 0x313, tPIPE = 0x214, tCARET = 0x215, - tNOT = 0x016, tANDNOT = 0x317, tAND = 0x018, tOR = 0x019, - tEQ = 0x11A, tGT = 0x11B, tGE = 0x11C, tLT = 0x11D, tLE = 0x11E, tNE = 0x11F, - tLEFT = 0x320, tRIGHT = 0x321, tINC = 0x022, tDEC = 0x023, + // RelOps (do not reorder) + tEQ = 0x102, tNE = 0x103, tLT = 0x104, tLE = 0x105, tGT = 0x106, tGE = 0x107, + // AddOps (do not reorder) + tPLUS = 0x208, tMINUS = 0x209, tPIPE = 0x20A, tCARET = 0x20B, + // MulOps (do not reorder) + tSTAR = 0x30C, tSLASH = 0x30D, tPERCENT = 0x30E, tAMP = 0x30F, + tANDNOT = 0x310, tLEFT = 0x311, tRIGHT = 0x312, + // UnaryOps + tNOT = 0x013, + // LogicalOps + tAND = 0x014, tOR = 0x015, tBANG = 0x016, + // Brackets, Braces, Parens + tOBRACK = 0x017, tCBRACK = 0x018, tOPAREN = 0x019, tCPAREN = 0x01A, + tOBRACE = 0x01B, tCBRACE = 0x01C, + // Various Punctuation + tSEMI = 0x01D, tCOLON = 0x1E, tDOT = 0x01F, tCOMMA = 0x020, + tINC = 0x021, tDEC = 0x022, tASSIGN = 0x023, + // Keywords tVAR = 0x024, tSTRUCT = 0x025, tFUNC = 0x026, tRETURN = 0x027, tIF = 0x028, tELSE = 0x029, tWHILE = 0x02A, tFOR = 0x02B, tBREAK = 0x02C, tCONTINUE = 0x02D, tSWITCH = 0x02E, tCASE = 0x02F, + // Special Constants tTRUE = 0x030, tFALSE = 0x031, tNIL = 0x032, + // Idenitfiers, Numbers, Strings tNAME = 0x033, tNUMBER = 0x034, tSTRING = 0x035, } token_t; char *tnames[] = { "<EOF>", "<EOL>", - ".", ",", ":", ";", "!", + "==", "!=", "<", "<=", ">", ">=", + "+", "-", "|", "^", + "*", "/", "%", "&", + "&~", "<<", ">>", + "~", + "&&", "||", "!", "[", "]", "(", ")", - "{", "}", "=", - "+", "-", "*", "/", - "%", "&", "|", "^", - "~", "&~", "&&", "||", - "==", ">", ">=", "<", "<=", "!=", - "<<", ">>", "++", "--", + "{", "}", + ";", ":", ".", ",", + "++", "--", "=", "var", "struct", "func", "return", "if", "else", "while", "for", "break", "continue", "switch", "case", @@ -59,6 +74,12 @@ char *tnames[] = { "<NAME>", "<NUMBER>", "<STRING>", }; +// encodings for ops in Items +enum { rEQ, rGT, rGE, rLT, rLE, rNE }; // RelOps +enum { aADD, aSUB, aIOR, aXOR }; // AddOps +enum { mMUL, mDIV, mMOD, mAND, mANN, mLSL, mLSR }; // MulOps + +u8 invert_relop_tab[6] = { rNE, rLE, rLT, rGE, rGT, rEQ }; typedef struct StringRec* String; typedef struct ObjectRec* Object; @@ -176,9 +197,11 @@ enum { // r a b iReg, // regno iRegInd, // regno offset iCond, // ccode f-chain t-chain + iComp, // comp regno-a regno-b iFunc, }; + // Item Flags #define ifReadOnly 1 @@ -729,6 +752,10 @@ void setitem(Item itm, u32 kind, Type type, u32 r, u32 a, u32 b) { itm->b = b; } +u32 invert_relop(u32 op) { + if (op > 5) { abort(); } + return invert_relop_tab[op]; +} // ================================================================ void parse_expr(Ctx ctx, Item x); @@ -807,7 +834,11 @@ void parse_unary_expr(Ctx ctx, Item x) { u32 op = ctx->tok; next(ctx); parse_unary_expr(ctx, x); - gen_unary_op(ctx, op, x); + if ((x->kind == iComp) && (op == tBANG)) { + x->r = invert_relop(x->r); + } else { + gen_unary_op(ctx, op, x); + } } else if (ctx->tok == tAMP) { next(ctx); error(ctx, "deref unsupported"); @@ -819,33 +850,33 @@ void parse_unary_expr(Ctx ctx, Item x) { void parse_mul_expr(Ctx ctx, Item x) { parse_unary_expr(ctx, x); while ((ctx->tok >> 8) == tcMULOP) { - u32 op = ctx->tok; + u32 mulop = ctx->tok - tSTAR; next(ctx); ItemRec y; parse_unary_expr(ctx, &y); - gen_mul_op(ctx, op, x, &y); + gen_mul_op(ctx, mulop, x, &y); } } void parse_add_expr(Ctx ctx, Item x) { parse_mul_expr(ctx, x); while ((ctx->tok >> 8) == tcADDOP) { - u32 op = ctx->tok; + u32 addop = ctx->tok - tPLUS; next(ctx); ItemRec y; parse_mul_expr(ctx, &y); - gen_add_op(ctx, op, x, &y); + gen_add_op(ctx, addop, x, &y); } } void parse_rel_expr(Ctx ctx, Item x) { parse_add_expr(ctx, x); - while ((ctx->tok >> 8) == tcRELOP) { - u32 op = ctx->tok; + if ((ctx->tok >> 8) == tcRELOP) { + u32 relop = ctx->tok - tEQ; next(ctx); ItemRec y; parse_add_expr(ctx, &y); - gen_rel_op(ctx, op, x, &y); + gen_rel_op(ctx, relop, x, &y); } } @@ -1257,49 +1288,23 @@ void emit_bi(Ctx ctx, u32 op, u32 off) { emit(ctx, ((0xE0 | op) << 24) | (off & 0xffffff)); } +u8 rel_op_to_cc_tab[6] = { EQ, NE, LT, LE, GT, GE }; +u32 add_op_to_ins_tab[4] = { ADD, SUB, IOR, XOR }; +u32 mul_op_to_ins_tab[7] = { MUL, DIV, MOD, AND, ANN, LSL, ASR }; + // ================================================================ -const char* item_kind(u32 n) { - if (n == iConst) { - return "const"; - } else if (n == iVar) { - return "var"; - } else if (n == iParam) { - return "param"; - } else if (n == iReg) { - return "reg"; - } else if (n == iRegInd) { - return "regind"; - } else if (n == iCond) { - return "cond"; - } else { - return "???"; - } +u32 rel_op_to_cc(u32 op) { + if (op > 5) { abort(); } + return rel_op_to_cc_tab[op]; } -void print_item(Item x) { - fprintf(stderr, "ITEM(%s)%s t=%p r=%u a=%08x b=%08x\n", - item_kind(x->kind), (x->flags & ifReadOnly) ? " RO" : "", - x->type, x->r, x->a, x->b); +u32 add_op_to_ins(u32 op) { + if (op > 3) { abort(); } + return add_op_to_ins_tab[op]; } - -u32 add_op_to_ins(Ctx ctx, u32 op) { - if (op == tPLUS) { return ADD; } - if (op == tMINUS) { return SUB; } - if (op == tPIPE) { return IOR; } - if (op == tCARET) { return XOR; } - error(ctx, "invalid add-op"); - return 0; -} -u32 mul_op_to_ins(Ctx ctx, u32 op) { - if (op == tSTAR) { return MUL; } - if (op == tSLASH) { return DIV; } - if (op == tPERCENT) { return MOD; } - if (op == tLEFT) { return LSL; } - if (op == tRIGHT) { return ASR; } - if (op == tAMP) { return AND; } - if (op == tANDNOT) { return ANN; } - error(ctx, "invalid mul-op"); - return 0; +u32 mul_op_to_ins(u32 op) { + if (op > 6) { abort(); }; + return mul_op_to_ins_tab[op]; } // check to see if the last emitted instruction @@ -1391,7 +1396,7 @@ void gen_call(Ctx ctx, Item x) { } void gen_add_op(Ctx ctx, u32 op, Item x, Item y) { - op = add_op_to_ins(ctx, op); + op = add_op_to_ins(op); if ((x->kind == iConst) && (y->kind == iConst)) { // XC = XC op YC if (op == ADD) { @@ -1420,7 +1425,7 @@ void gen_add_op(Ctx ctx, u32 op, Item x, Item y) { } void gen_mul_op(Ctx ctx, u32 op, Item x, Item y) { - op = mul_op_to_ins(ctx, op); + op = mul_op_to_ins(op); if ((x->kind == iConst) && (y->kind == iConst)) { // XC = XC op YC if (op == MUL) { @@ -1470,7 +1475,12 @@ void gen_mul_op(Ctx ctx, u32 op, Item x, Item y) { } void gen_rel_op(Ctx ctx, u32 op, Item x, Item y) { - error(ctx, "rel-op unsupported"); + gen_load(ctx, x); + gen_load(ctx, y); + x->kind = iComp; + x->a = x->r; + x->b = y->r; + x->r = op; } void gen_unary_op(Ctx ctx, u32 op, Item x) { @@ -1484,18 +1494,17 @@ void gen_unary_op(Ctx ctx, u32 op, Item x) { } return; } - u32 t0 = get_reg_tmp(ctx); - gen_load(ctx, x); - if (op == tMINUS) { + if (op == tBANG) { + emit_opi_n(ctx, XOR, x->r, x->r, 1); + } else if (op == tNOT) { + emit_opi_n(ctx, XOR, x->r, x->r, 0xFFFFFFFF); + } else if (op == tMINUS) { + u32 t0 = get_reg_tmp(ctx); + gen_load(ctx, x); emit_mov(ctx, t0, 0); emit_op(ctx, SUB, x->r, t0, x->r); - } else if (op == tBANG) { - error(ctx, "unary bool not unsupported"); - } else if (op == tNOT) { - emit_mov(ctx, t0, 0xFFFFFFFF); - emit_op(ctx, XOR, x->r, x->r, t0); + put_reg(ctx, t0); } - put_reg(ctx, t0); } void gen_fixups(Ctx ctx, Fixup fixup) {