add boolean logic
This commit is contained in:
parent
d185396a1c
commit
84785dc3cf
@ -3,7 +3,7 @@ k := 0
|
|||||||
|
|
||||||
iterations := 100
|
iterations := 100
|
||||||
|
|
||||||
while k - iterations {
|
while k < iterations {
|
||||||
k_f := float(k)
|
k_f := float(k)
|
||||||
sum = sum + 1.0 / pow(16.0, k_f) *
|
sum = sum + 1.0 / pow(16.0, k_f) *
|
||||||
(4.0 / (8.0 * k_f + 1.0) -
|
(4.0 / (8.0 * k_f + 1.0) -
|
||||||
|
10
ir.c
10
ir.c
@ -10,6 +10,10 @@ const char *irinstr_str[IRInstrEnumSize] = {
|
|||||||
[IRSub] = "sub",
|
[IRSub] = "sub",
|
||||||
[IRMul] = "mul",
|
[IRMul] = "mul",
|
||||||
[IRDiv] = "div",
|
[IRDiv] = "div",
|
||||||
|
[IREq] = "eq",
|
||||||
|
[IRLt] = "lt",
|
||||||
|
[IRLe] = "le",
|
||||||
|
[IRNot] = "not",
|
||||||
[IRJmp] = "jmp",
|
[IRJmp] = "jmp",
|
||||||
[IRJnz] = "jnz",
|
[IRJnz] = "jnz",
|
||||||
[IRCallInternal] = "calli",
|
[IRCallInternal] = "calli",
|
||||||
@ -77,6 +81,9 @@ static void print_val(const Value *v) {
|
|||||||
case TypeInt:
|
case TypeInt:
|
||||||
printf("%zd", v->Int);
|
printf("%zd", v->Int);
|
||||||
break;
|
break;
|
||||||
|
case TypeBool:
|
||||||
|
printf("%s", v->Bool ? "true" : "false");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("(unknown type)");
|
printf("(unknown type)");
|
||||||
break;
|
break;
|
||||||
@ -105,6 +112,9 @@ void print_ir(IRToks *v, const BuiltinFunc *builtin_funcs) {
|
|||||||
case IRSub:
|
case IRSub:
|
||||||
case IRDiv:
|
case IRDiv:
|
||||||
case IRMul:
|
case IRMul:
|
||||||
|
case IREq:
|
||||||
|
case IRLt:
|
||||||
|
case IRLe:
|
||||||
printf(" %%%zx ", v->toks[i].Binary.addr);
|
printf(" %%%zx ", v->toks[i].Binary.addr);
|
||||||
print_irparam(&v->toks[i].Binary.lhs);
|
print_irparam(&v->toks[i].Binary.lhs);
|
||||||
printf(" ");
|
printf(" ");
|
||||||
|
4
ir.h
4
ir.h
@ -18,6 +18,10 @@ enum IRInstr {
|
|||||||
IRSub,
|
IRSub,
|
||||||
IRMul,
|
IRMul,
|
||||||
IRDiv,
|
IRDiv,
|
||||||
|
IREq,
|
||||||
|
IRLt,
|
||||||
|
IRLe,
|
||||||
|
IRNot,
|
||||||
IRJmp,
|
IRJmp,
|
||||||
IRJnz,
|
IRJnz,
|
||||||
IRCallInternal,
|
IRCallInternal,
|
||||||
|
35
lex.c
35
lex.c
@ -58,6 +58,10 @@ TokList lex(const char *s) {
|
|||||||
emit(&toks, &pos, (Tok){ .kind = TokElse });
|
emit(&toks, &pos, (Tok){ .kind = TokElse });
|
||||||
else if (streq_0_n("while", start, i))
|
else if (streq_0_n("while", start, i))
|
||||||
emit(&toks, &pos, (Tok){ .kind = TokWhile });
|
emit(&toks, &pos, (Tok){ .kind = TokWhile });
|
||||||
|
else if (streq_0_n("true", start, i))
|
||||||
|
emit(&toks, &pos, (Tok){ .kind = TokVal, .Val = { .type = { .kind = TypeBool, }, .Bool = true, }, });
|
||||||
|
else if (streq_0_n("false", start, i))
|
||||||
|
emit(&toks, &pos, (Tok){ .kind = TokVal, .Val = { .type = { .kind = TypeBool, }, .Bool = false, }, });
|
||||||
else {
|
else {
|
||||||
emit(&toks, &pos, (Tok){
|
emit(&toks, &pos, (Tok){
|
||||||
.kind = TokIdent,
|
.kind = TokIdent,
|
||||||
@ -162,15 +166,39 @@ TokList lex(const char *s) {
|
|||||||
break;
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
consume(&pos, *(s++));
|
consume(&pos, *(s++));
|
||||||
if (s[0] == '=') {
|
if (s[0] == '=')
|
||||||
emit(&toks, &pos, (Tok){ .kind = TokDeclare });
|
emit(&toks, &pos, (Tok){ .kind = TokDeclare });
|
||||||
} else {
|
else {
|
||||||
set_err("Expected ':='");
|
set_err("Expected ':='");
|
||||||
return toks;
|
return toks;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '=':
|
case '=':
|
||||||
emit(&toks, &pos, (Tok){ .kind = TokAssign });
|
consume(&pos, *(s++));
|
||||||
|
if (s[0] == '=')
|
||||||
|
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpEq });
|
||||||
|
else {
|
||||||
|
emit(&toks, &pos, (Tok){ .kind = TokAssign });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
consume(&pos, *(s++));
|
||||||
|
if (s[0] == '=')
|
||||||
|
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpLe });
|
||||||
|
else {
|
||||||
|
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpLt });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
consume(&pos, *(s++));
|
||||||
|
if (s[0] == '=')
|
||||||
|
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpGe });
|
||||||
|
else {
|
||||||
|
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpGt });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case '{':
|
case '{':
|
||||||
case '}':
|
case '}':
|
||||||
@ -180,6 +208,7 @@ TokList lex(const char *s) {
|
|||||||
case '+':
|
case '+':
|
||||||
case '-':
|
case '-':
|
||||||
case '*':
|
case '*':
|
||||||
|
case '!':
|
||||||
emit(&toks, &pos, (Tok){
|
emit(&toks, &pos, (Tok){
|
||||||
.kind = TokOp,
|
.kind = TokOp,
|
||||||
.Op = s[0],
|
.Op = s[0],
|
||||||
|
7
main.c
7
main.c
@ -35,9 +35,10 @@ static void die(const char *fmt, ...) {
|
|||||||
|
|
||||||
static Value fn_print(Value *args) {
|
static Value fn_print(Value *args) {
|
||||||
switch (args[0].type.kind) {
|
switch (args[0].type.kind) {
|
||||||
case TypeVoid: printf("(void)\n"); break;
|
case TypeVoid: printf("(void)\n"); break;
|
||||||
case TypeFloat: printf("%f\n", args[0].Float); break;
|
case TypeFloat: printf("%f\n", args[0].Float); break;
|
||||||
case TypeInt: printf("%zd\n", args[0].Int); break;
|
case TypeInt: printf("%zd\n", args[0].Int); break;
|
||||||
|
case TypeBool: printf("%s\n", args[0].Bool ? "true" : "false"); break;
|
||||||
default:
|
default:
|
||||||
ASSERT_UNREACHED();
|
ASSERT_UNREACHED();
|
||||||
}
|
}
|
||||||
|
51
parse.c
51
parse.c
@ -46,12 +46,16 @@ static void set_irtok_dest_addr(IRTok *t, size_t addr) {
|
|||||||
switch (t->instr) {
|
switch (t->instr) {
|
||||||
case IRSet:
|
case IRSet:
|
||||||
case IRNeg:
|
case IRNeg:
|
||||||
|
case IRNot:
|
||||||
t->Unary.addr = addr;
|
t->Unary.addr = addr;
|
||||||
break;
|
break;
|
||||||
case IRAdd:
|
case IRAdd:
|
||||||
case IRSub:
|
case IRSub:
|
||||||
case IRMul:
|
case IRMul:
|
||||||
case IRDiv:
|
case IRDiv:
|
||||||
|
case IREq:
|
||||||
|
case IRLt:
|
||||||
|
case IRLe:
|
||||||
t->Binary.addr = addr;
|
t->Binary.addr = addr;
|
||||||
break;
|
break;
|
||||||
case IRCallInternal:
|
case IRCallInternal:
|
||||||
@ -172,11 +176,19 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
|
|||||||
Scope sc = make_scope(parent_sc, false);
|
Scope sc = make_scope(parent_sc, false);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Prepare to collapse negative factor. */
|
/* Prepare to collapse unary operation. */
|
||||||
bool negate = false;
|
bool perform_unary = false;
|
||||||
if (t->tok.kind == TokOp && t->tok.Op == OpSub) {
|
IRInstr unary_op;
|
||||||
t = t->next;
|
if (t->tok.kind == TokOp) {
|
||||||
negate = true;
|
if (t->tok.Op == OpSub) {
|
||||||
|
t = t->next;
|
||||||
|
perform_unary = true;
|
||||||
|
unary_op = IRNeg;
|
||||||
|
} else if (t->tok.Op == OpNot) {
|
||||||
|
t = t->next;
|
||||||
|
perform_unary = true;
|
||||||
|
unary_op = IRNot;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete newline if we're definitely expecting an operand. */
|
/* Delete newline if we're definitely expecting an operand. */
|
||||||
@ -312,28 +324,28 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Collapse negative factor. */
|
/* Collapse unary operation. */
|
||||||
if (negate) {
|
if (perform_unary) {
|
||||||
Tok *v = &t->tok; /* what we want to negate */
|
Tok *v = &t->tok; /* what we want to perform the operation on */
|
||||||
t = t->prev; /* go back to the '-' sign */
|
t = t->prev; /* go back to the '-' sign */
|
||||||
toklist_del(toks, t->next, t->next); /* again, just removing the reference */
|
toklist_del(toks, t->next, t->next); /* again, just removing the reference */
|
||||||
|
|
||||||
bool is_last_operation = t == start && t->next->tok.kind == TokOp && op_prec[t->next->tok.Op] == PREC_DELIM;
|
bool is_last_operation = t == start && t->next->tok.kind == TokOp && op_prec[t->next->tok.Op] == PREC_DELIM;
|
||||||
|
|
||||||
if (v->kind == TokVal) {
|
if (v->kind == TokVal) {
|
||||||
/* immediately negate value */
|
/* immediately perform operation */
|
||||||
t->tok.kind = TokVal;
|
t->tok.kind = TokVal;
|
||||||
t->tok.Val = eval_unary(IRNeg, &v->Val);
|
TRY_RET(t->tok.Val = eval_unary(unary_op, &v->Val), (ExprRet){0});
|
||||||
} else {
|
} else {
|
||||||
size_t res_addr = is_last_operation ? 0 : sc.mem_addr++;
|
size_t res_addr = is_last_operation ? 0 : sc.mem_addr++;
|
||||||
|
|
||||||
/* Instruction to negate. */
|
/* unary IR instruction */
|
||||||
IRParam v_irparam;
|
IRParam v_irparam;
|
||||||
TRY_RET(v_irparam = tok_to_irparam(&sc, v), (ExprRet){0});
|
TRY_RET(v_irparam = tok_to_irparam(&sc, v), (ExprRet){0});
|
||||||
IRTok ir = {
|
IRTok ir = {
|
||||||
.ln = t->tok.ln,
|
.ln = t->tok.ln,
|
||||||
.col = t->tok.col,
|
.col = t->tok.col,
|
||||||
.instr = IRNeg,
|
.instr = unary_op,
|
||||||
.Unary = {
|
.Unary = {
|
||||||
.addr = res_addr,
|
.addr = res_addr,
|
||||||
.val = v_irparam,
|
.val = v_irparam,
|
||||||
@ -421,12 +433,19 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
|
|||||||
* because we're still using their values later on) */
|
* because we're still using their values later on) */
|
||||||
toklist_del(toks, t->next, t->next->next);
|
toklist_del(toks, t->next, t->next->next);
|
||||||
|
|
||||||
|
bool swap_operands = false;
|
||||||
|
|
||||||
IRInstr instr;
|
IRInstr instr;
|
||||||
switch (l_op->Op) {
|
switch (l_op->Op) {
|
||||||
case OpAdd: instr = IRAdd; break;
|
case OpAdd: instr = IRAdd; break;
|
||||||
case OpSub: instr = IRSub; break;
|
case OpSub: instr = IRSub; break;
|
||||||
case OpMul: instr = IRMul; break;
|
case OpMul: instr = IRMul; break;
|
||||||
case OpDiv: instr = IRDiv; break;
|
case OpDiv: instr = IRDiv; break;
|
||||||
|
case OpEq: instr = IREq; break;
|
||||||
|
case OpLt: instr = IRLt; break;
|
||||||
|
case OpLe: instr = IRLe; break;
|
||||||
|
case OpGt: instr = IRLt; swap_operands = true; break;
|
||||||
|
case OpGe: instr = IRLe; swap_operands = true; break;
|
||||||
default:
|
default:
|
||||||
mark_err(l_op);
|
mark_err(l_op);
|
||||||
set_err("Unknown operation: '%s'", op_str[l_op->Op]);
|
set_err("Unknown operation: '%s'", op_str[l_op->Op]);
|
||||||
@ -435,8 +454,10 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
|
|||||||
|
|
||||||
if (lhs->kind == TokVal && rhs->kind == TokVal) {
|
if (lhs->kind == TokVal && rhs->kind == TokVal) {
|
||||||
/* evaluate the constant expression immediately */
|
/* evaluate the constant expression immediately */
|
||||||
|
Value *lhs_val = swap_operands ? &rhs->Val : &lhs->Val;
|
||||||
|
Value *rhs_val = swap_operands ? &lhs->Val : &rhs->Val;
|
||||||
lhs->kind = TokVal;
|
lhs->kind = TokVal;
|
||||||
TRY_RET(lhs->Val = eval_binary(instr, &lhs->Val, &rhs->Val), (ExprRet){0});
|
TRY_RET(lhs->Val = eval_binary(instr, lhs_val, rhs_val), (ExprRet){0});
|
||||||
} else {
|
} else {
|
||||||
bool is_last_operation = t == start && r_op_prec == PREC_DELIM;
|
bool is_last_operation = t == start && r_op_prec == PREC_DELIM;
|
||||||
|
|
||||||
@ -452,8 +473,8 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
|
|||||||
.instr = instr,
|
.instr = instr,
|
||||||
.Binary = {
|
.Binary = {
|
||||||
.addr = res_addr,
|
.addr = res_addr,
|
||||||
.lhs = lhs_irparam,
|
.lhs = swap_operands ? rhs_irparam : lhs_irparam,
|
||||||
.rhs = rhs_irparam,
|
.rhs = swap_operands ? lhs_irparam : rhs_irparam,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
41
runtime.c
41
runtime.c
@ -39,6 +39,32 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
|
|||||||
return (Value){0};
|
return (Value){0};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case IREq:
|
||||||
|
case IRLt:
|
||||||
|
case IRLe:
|
||||||
|
bool res;
|
||||||
|
if (lhs->type.kind == TypeInt && rhs->type.kind == TypeInt) {
|
||||||
|
switch (instr) {
|
||||||
|
case IREq: res = lhs->Int == rhs->Int; break;
|
||||||
|
case IRLt: res = lhs->Int < rhs->Int; break;
|
||||||
|
case IRLe: res = lhs->Int <= rhs->Int; break;
|
||||||
|
default: ASSERT_UNREACHED();
|
||||||
|
};
|
||||||
|
} else if (lhs->type.kind == TypeFloat && rhs->type.kind == TypeFloat) {
|
||||||
|
switch (instr) {
|
||||||
|
case IREq: res = lhs->Float == rhs->Float; break;
|
||||||
|
case IRLt: res = lhs->Float < rhs->Float; break;
|
||||||
|
case IRLe: res = lhs->Float <= rhs->Float; break;
|
||||||
|
default: ASSERT_UNREACHED();
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
set_err("Unsupported types for operation '%s'", irinstr_str[instr]);
|
||||||
|
return (Value){0};
|
||||||
|
}
|
||||||
|
return (Value){
|
||||||
|
.type.kind = TypeBool,
|
||||||
|
.Bool = res,
|
||||||
|
};
|
||||||
default:
|
default:
|
||||||
ASSERT_UNREACHED();
|
ASSERT_UNREACHED();
|
||||||
}
|
}
|
||||||
@ -55,7 +81,14 @@ Value eval_unary(IRInstr instr, const Value *v) {
|
|||||||
else if (v->type.kind == TypeFloat)
|
else if (v->type.kind == TypeFloat)
|
||||||
return (Value){ .type.kind = TypeFloat, .Float = -v->Float };
|
return (Value){ .type.kind = TypeFloat, .Float = -v->Float };
|
||||||
else {
|
else {
|
||||||
set_err("Unsupported types for operation '%s'", irinstr_str[instr]);
|
set_err("Unsupported type for operation '%s'", irinstr_str[instr]);
|
||||||
|
return (Value){0};
|
||||||
|
}
|
||||||
|
case IRNot:
|
||||||
|
if (v->type.kind == TypeBool) {
|
||||||
|
return (Value){ .type.kind = TypeBool, .Bool = !v->Bool };
|
||||||
|
} else {
|
||||||
|
set_err("Unsupported type for operation '%s'", irinstr_str[instr]);
|
||||||
return (Value){0};
|
return (Value){0};
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -67,6 +100,7 @@ bool is_nonzero(const Value *v) {
|
|||||||
switch (v->type.kind) {
|
switch (v->type.kind) {
|
||||||
case TypeInt: return v->Int != 0;
|
case TypeInt: return v->Int != 0;
|
||||||
case TypeFloat: return v->Float != 0.0;
|
case TypeFloat: return v->Float != 0.0;
|
||||||
|
case TypeBool: return v->Bool;
|
||||||
default: ASSERT_UNREACHED();
|
default: ASSERT_UNREACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,8 +109,9 @@ Value zero_val(Type ty) {
|
|||||||
Value ret;
|
Value ret;
|
||||||
ret.type = ty;
|
ret.type = ty;
|
||||||
switch (ty.kind) {
|
switch (ty.kind) {
|
||||||
case TypeInt: ret.Int = 0; break;
|
case TypeInt: ret.Int = 0; break;
|
||||||
case TypeFloat: ret.Float = 0.0; break;
|
case TypeFloat: ret.Float = 0.0; break;
|
||||||
|
case TypeBool: ret.Bool = false; break;
|
||||||
default: ASSERT_UNREACHED();
|
default: ASSERT_UNREACHED();
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
22
tok.c
22
tok.c
@ -11,10 +11,15 @@ int8_t op_prec[OperatorEnumSize] = {
|
|||||||
[OpLCurl] = PREC_DELIM,
|
[OpLCurl] = PREC_DELIM,
|
||||||
[OpRParen] = PREC_DELIM,
|
[OpRParen] = PREC_DELIM,
|
||||||
[OpComma] = PREC_DELIM,
|
[OpComma] = PREC_DELIM,
|
||||||
[OpAdd] = 0,
|
[OpEq] = 0,
|
||||||
[OpSub] = 0,
|
[OpLt] = 0,
|
||||||
[OpMul] = 1,
|
[OpGt] = 0,
|
||||||
[OpDiv] = 1,
|
[OpLe] = 0,
|
||||||
|
[OpGe] = 0,
|
||||||
|
[OpAdd] = 1,
|
||||||
|
[OpSub] = 1,
|
||||||
|
[OpMul] = 2,
|
||||||
|
[OpDiv] = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *op_str[OperatorEnumSize] = {
|
const char *op_str[OperatorEnumSize] = {
|
||||||
@ -27,8 +32,14 @@ const char *op_str[OperatorEnumSize] = {
|
|||||||
[OpSub] = "-",
|
[OpSub] = "-",
|
||||||
[OpMul] = "*",
|
[OpMul] = "*",
|
||||||
[OpDiv] = "/",
|
[OpDiv] = "/",
|
||||||
|
[OpNot] = "!",
|
||||||
[OpNewLn] = "\\n",
|
[OpNewLn] = "\\n",
|
||||||
[OpEOF] = "EOF",
|
[OpEOF] = "EOF",
|
||||||
|
[OpEq] = "==",
|
||||||
|
[OpLt] = "<",
|
||||||
|
[OpGt] = ">",
|
||||||
|
[OpLe] = "<=",
|
||||||
|
[OpGe] = ">=",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *tok_str[TokKindEnumSize] = {
|
const char *tok_str[TokKindEnumSize] = {
|
||||||
@ -101,6 +112,9 @@ void print_toks(TokList *l) {
|
|||||||
case TypeInt:
|
case TypeInt:
|
||||||
printf(": " C_ICYAN "%zd" C_RESET, i->tok.Val.Int);
|
printf(": " C_ICYAN "%zd" C_RESET, i->tok.Val.Int);
|
||||||
break;
|
break;
|
||||||
|
case TypeBool:
|
||||||
|
printf(": " C_ICYAN "%s" C_RESET, i->tok.Val.Bool ? "true" : "false");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf(" " C_ICYAN "(unknown type)" C_RESET);
|
printf(" " C_ICYAN "(unknown type)" C_RESET);
|
||||||
break;
|
break;
|
||||||
|
8
tok.h
8
tok.h
@ -11,6 +11,7 @@ typedef struct Type {
|
|||||||
TypeVoid = 0,
|
TypeVoid = 0,
|
||||||
TypeFloat,
|
TypeFloat,
|
||||||
TypeInt,
|
TypeInt,
|
||||||
|
TypeBool,
|
||||||
} kind;
|
} kind;
|
||||||
|
|
||||||
/*union {
|
/*union {
|
||||||
@ -23,6 +24,7 @@ typedef struct Value {
|
|||||||
union {
|
union {
|
||||||
double Float;
|
double Float;
|
||||||
ssize_t Int;
|
ssize_t Int;
|
||||||
|
bool Bool;
|
||||||
};
|
};
|
||||||
} Value;
|
} Value;
|
||||||
|
|
||||||
@ -36,7 +38,13 @@ enum Operator {
|
|||||||
OpSub = '-',
|
OpSub = '-',
|
||||||
OpMul = '*',
|
OpMul = '*',
|
||||||
OpDiv = '/',
|
OpDiv = '/',
|
||||||
|
OpNot = '!',
|
||||||
OpBeginNonchars = 256,
|
OpBeginNonchars = 256,
|
||||||
|
OpEq,
|
||||||
|
OpLt,
|
||||||
|
OpGt,
|
||||||
|
OpLe,
|
||||||
|
OpGe,
|
||||||
OpNewLn,
|
OpNewLn,
|
||||||
OpEOF,
|
OpEOF,
|
||||||
OperatorEnumSize,
|
OperatorEnumSize,
|
||||||
|
4
vm.c
4
vm.c
@ -55,6 +55,7 @@ void run(const IRToks *ir, const BuiltinFunc *builtin_funcs) {
|
|||||||
switch (instr->instr) {
|
switch (instr->instr) {
|
||||||
case IRSet:
|
case IRSet:
|
||||||
case IRNeg:
|
case IRNeg:
|
||||||
|
case IRNot:
|
||||||
stack_fit(&s, instr->Unary.addr);
|
stack_fit(&s, instr->Unary.addr);
|
||||||
TRY_ELSE(s.mem[instr->Unary.addr] = eval_unary(instr->instr, irparam_to_val(&s, &instr->Unary.val)),
|
TRY_ELSE(s.mem[instr->Unary.addr] = eval_unary(instr->instr, irparam_to_val(&s, &instr->Unary.val)),
|
||||||
{free(fn_args); stack_term(&s);});
|
{free(fn_args); stack_term(&s);});
|
||||||
@ -63,6 +64,9 @@ void run(const IRToks *ir, const BuiltinFunc *builtin_funcs) {
|
|||||||
case IRSub:
|
case IRSub:
|
||||||
case IRDiv:
|
case IRDiv:
|
||||||
case IRMul:
|
case IRMul:
|
||||||
|
case IREq:
|
||||||
|
case IRLt:
|
||||||
|
case IRLe:
|
||||||
stack_fit(&s, instr->Binary.addr);
|
stack_fit(&s, instr->Binary.addr);
|
||||||
TRY_ELSE(s.mem[instr->Binary.addr] = eval_binary(instr->instr,
|
TRY_ELSE(s.mem[instr->Binary.addr] = eval_binary(instr->instr,
|
||||||
irparam_to_val(&s, &instr->Binary.lhs),
|
irparam_to_val(&s, &instr->Binary.lhs),
|
||||||
|
Loading…
Reference in New Issue
Block a user