CIR Playground
Load example...
CIR on GitHub
Input
Run
// @bf() macro that uses the low-level compiler API, // and is thus very verbose. #include <cir.h> #include <cirm.h> #include <stdio.h> static CirCodeId bf(const char *code) { CirStmtId stmtId; const CirValue *args[3]; CirCodeId outCodeId = CirCode_ofExpr(NULL); // char memVar[3000]; CirVarId memVarId = CirVar_new(outCodeId); CirVar_setType(memVarId, @CirM_type(__typeval(char[3000]))); // char *memPtr; CirVarId memPtrId = CirVar_new(outCodeId); CirVar_setType(memPtrId, @CirM_type(__typeval(char *))); // [memPtrId] = [memVarId] stmtId = CirCode_appendNewStmt(outCodeId); CirStmt_toUnOp(stmtId, CirValue_ofVar(memPtrId), CIR_UNOP_IDENTITY, CirValue_ofVar(memVarId)); // memset([memVarId], 0, 3000); stmtId = CirCode_appendNewStmt(outCodeId); args[0] = CirValue_ofVar(memVarId); args[1] = CirValue_ofI64(CIR_IINT, 0); args[2] = CirValue_ofU64(CIR_IUINT, 3000); CirStmt_toCall(stmtId, NULL, @CirM_value(memset), args, 3); CirStmtId jumpStack[100]; unsigned jumpStackLen = 0; while (*code) { char c = *code; int count; if (c == '>') { for (count = 0; *code == '>'; count = count + 1, code = code + 1); // [memPtrId] += count; stmtId = CirCode_appendNewStmt(outCodeId); CirStmt_toBinOp(stmtId, CirValue_ofVar(memPtrId), CIR_BINOP_PLUS, CirValue_ofVar(memPtrId), CirValue_ofI64(CIR_IINT, count)); } else if (c == '<') { for (count = 0; *code == '<'; count = count + 1, code = code + 1); // [memPtrId] -= count; stmtId = CirCode_appendNewStmt(outCodeId); CirStmt_toBinOp(stmtId, CirValue_ofVar(memPtrId), CIR_BINOP_MINUS, CirValue_ofVar(memPtrId), CirValue_ofI64(CIR_IINT, count)); } else if (c == '+') { for (count = 0; *code == '+'; count = count + 1, code = code + 1); // *[memPtrId] += count; stmtId = CirCode_appendNewStmt(outCodeId); CirStmt_toBinOp(stmtId, CirValue_ofMem(memPtrId), CIR_BINOP_PLUS, CirValue_ofMem(memPtrId), CirValue_ofI64(CIR_IINT, count)); } else if (c == '-') { for (count = 0; *code == '-'; count = count + 1, code = code + 1); // *[memPtrId] -= count; stmtId = CirCode_appendNewStmt(outCodeId); CirStmt_toBinOp(stmtId, CirValue_ofMem(memPtrId), CIR_BINOP_MINUS, CirValue_ofMem(memPtrId), CirValue_ofI64(CIR_IINT, count)); } else if (c == '.') { // putchar(*[memPtrId]); stmtId = CirCode_appendNewStmt(outCodeId); args[0] = CirValue_ofMem(memPtrId); CirStmt_toCall(stmtId, NULL, @CirM_value(putchar), args, 1); ++code; } else if (c == ',') { // *[memPtrId] = getchar(); stmtId = CirCode_appendNewStmt(outCodeId); CirStmt_toCall(stmtId, CirValue_ofMem(memPtrId), @CirM_value(getchar), NULL, 0); ++code; } else if (c == '[') { // Cmp (we don't know jump target yet) stmtId = CirCode_appendNewStmt(outCodeId); CirStmt_toCmp(stmtId, CIR_CONDOP_EQ, CirValue_ofMem(memPtrId), CirValue_ofI64(CIR_IINT, 0), 0); jumpStack[jumpStackLen++] = stmtId; ++code; } else if (c == ']') { // Backpatch CirStmtId targetJump = jumpStack[--jumpStackLen]; stmtId = CirCode_appendNewStmt(outCodeId); CirStmt_toGoto(stmtId, targetJump); stmtId = CirCode_appendNewStmt(outCodeId); CirStmt_setJumpTarget(targetJump, stmtId); ++code; } else { ++code; } } return outCodeId; } int main(void) { // Hello World @bf("++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."); return 0; }
stdout
stderr
Load Example...
×
00 - Compile-time fibonacci
01 - Inline Repeat
02 - Compile-time strtok
03 - Does a code call a function
04 - C Preprocessor identifiers may be accidentally shadowed
05 - CIR identifiers won't be accidentally shadowed
06 - C Preprocessor accidental capture of symbols
07 - CIR won't accidentally capture symbols
08 - bf-to-C (low level ver)
09 - bf-to-C (with quote-antiquote)
10 - async-await
11 - Embed an external file
12 - zlib