add logical or and logical and
This commit is contained in:
parent
d67008cfbf
commit
6bdc4e3210
4
ir.c
4
ir.c
@ -14,6 +14,8 @@ const char *irinstr_str[IRInstrEnumSize] = {
|
|||||||
[IRLt] = "lt",
|
[IRLt] = "lt",
|
||||||
[IRLe] = "le",
|
[IRLe] = "le",
|
||||||
[IRNot] = "not",
|
[IRNot] = "not",
|
||||||
|
[IRAnd] = "and",
|
||||||
|
[IROr] = "or",
|
||||||
[IRJmp] = "jmp",
|
[IRJmp] = "jmp",
|
||||||
[IRJnz] = "jnz",
|
[IRJnz] = "jnz",
|
||||||
[IRCallInternal] = "calli",
|
[IRCallInternal] = "calli",
|
||||||
@ -119,6 +121,8 @@ void print_ir(IRToks *v, const BuiltinFunc *builtin_funcs) {
|
|||||||
case IREq:
|
case IREq:
|
||||||
case IRLt:
|
case IRLt:
|
||||||
case IRLe:
|
case IRLe:
|
||||||
|
case IRAnd:
|
||||||
|
case IROr:
|
||||||
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(" ");
|
||||||
|
2
ir.h
2
ir.h
@ -22,6 +22,8 @@ enum IRInstr {
|
|||||||
IRLt,
|
IRLt,
|
||||||
IRLe,
|
IRLe,
|
||||||
IRNot,
|
IRNot,
|
||||||
|
IRAnd,
|
||||||
|
IROr,
|
||||||
IRJmp,
|
IRJmp,
|
||||||
IRJnz,
|
IRJnz,
|
||||||
IRCallInternal,
|
IRCallInternal,
|
||||||
|
14
lex.c
14
lex.c
@ -218,6 +218,20 @@ TokList lex(const char *s) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case '&':
|
||||||
|
consume(&pos, *(s++));
|
||||||
|
if (s[0] == '&') {
|
||||||
|
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpAnd });
|
||||||
|
} else
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
case '|':
|
||||||
|
consume(&pos, *(s++));
|
||||||
|
if (s[0] == '|') {
|
||||||
|
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpOr });
|
||||||
|
} else
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
case '{':
|
case '{':
|
||||||
case '}':
|
case '}':
|
||||||
case '(':
|
case '(':
|
||||||
|
4
parse.c
4
parse.c
@ -56,6 +56,8 @@ static void set_irtok_dest_addr(IRTok *t, size_t addr) {
|
|||||||
case IREq:
|
case IREq:
|
||||||
case IRLt:
|
case IRLt:
|
||||||
case IRLe:
|
case IRLe:
|
||||||
|
case IRAnd:
|
||||||
|
case IROr:
|
||||||
t->Binary.addr = addr;
|
t->Binary.addr = addr;
|
||||||
break;
|
break;
|
||||||
case IRCallInternal:
|
case IRCallInternal:
|
||||||
@ -446,6 +448,8 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
|
|||||||
case OpLe: instr = IRLe; break;
|
case OpLe: instr = IRLe; break;
|
||||||
case OpGt: instr = IRLt; swap_operands = true; break;
|
case OpGt: instr = IRLt; swap_operands = true; break;
|
||||||
case OpGe: instr = IRLe; swap_operands = true; break;
|
case OpGe: instr = IRLe; swap_operands = true; break;
|
||||||
|
case OpAnd: instr = IRAnd; break;
|
||||||
|
case OpOr: instr = IROr; 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]);
|
||||||
|
12
runtime.c
12
runtime.c
@ -65,6 +65,18 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
|
|||||||
.type.kind = TypeBool,
|
.type.kind = TypeBool,
|
||||||
.Bool = res,
|
.Bool = res,
|
||||||
};
|
};
|
||||||
|
case IRAnd:
|
||||||
|
return (Value){
|
||||||
|
.type.kind = TypeBool,
|
||||||
|
.Bool = is_nonzero(lhs) && is_nonzero(rhs),
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case IROr:
|
||||||
|
return (Value){
|
||||||
|
.type.kind = TypeBool,
|
||||||
|
.Bool = is_nonzero(lhs) || is_nonzero(rhs),
|
||||||
|
};
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT_UNREACHED();
|
ASSERT_UNREACHED();
|
||||||
}
|
}
|
||||||
|
22
tok.c
22
tok.c
@ -11,15 +11,17 @@ int8_t op_prec[OperatorEnumSize] = {
|
|||||||
[OpLCurl] = PREC_DELIM,
|
[OpLCurl] = PREC_DELIM,
|
||||||
[OpRParen] = PREC_DELIM,
|
[OpRParen] = PREC_DELIM,
|
||||||
[OpComma] = PREC_DELIM,
|
[OpComma] = PREC_DELIM,
|
||||||
[OpEq] = 0,
|
[OpAnd] = 0,
|
||||||
[OpLt] = 0,
|
[OpOr] = 0,
|
||||||
[OpGt] = 0,
|
[OpEq] = 1,
|
||||||
[OpLe] = 0,
|
[OpLt] = 1,
|
||||||
[OpGe] = 0,
|
[OpGt] = 1,
|
||||||
[OpAdd] = 1,
|
[OpLe] = 1,
|
||||||
[OpSub] = 1,
|
[OpGe] = 1,
|
||||||
[OpMul] = 2,
|
[OpAdd] = 2,
|
||||||
[OpDiv] = 2,
|
[OpSub] = 2,
|
||||||
|
[OpMul] = 3,
|
||||||
|
[OpDiv] = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *op_str[OperatorEnumSize] = {
|
const char *op_str[OperatorEnumSize] = {
|
||||||
@ -40,6 +42,8 @@ const char *op_str[OperatorEnumSize] = {
|
|||||||
[OpGt] = ">",
|
[OpGt] = ">",
|
||||||
[OpLe] = "<=",
|
[OpLe] = "<=",
|
||||||
[OpGe] = ">=",
|
[OpGe] = ">=",
|
||||||
|
[OpAnd] = "&&",
|
||||||
|
[OpOr] = "||",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *tok_str[TokKindEnumSize] = {
|
const char *tok_str[TokKindEnumSize] = {
|
||||||
|
2
tok.h
2
tok.h
@ -47,6 +47,8 @@ enum Operator {
|
|||||||
OpGt,
|
OpGt,
|
||||||
OpLe,
|
OpLe,
|
||||||
OpGe,
|
OpGe,
|
||||||
|
OpAnd,
|
||||||
|
OpOr,
|
||||||
OpNewLn,
|
OpNewLn,
|
||||||
OpEOF,
|
OpEOF,
|
||||||
OperatorEnumSize,
|
OperatorEnumSize,
|
||||||
|
2
vm.c
2
vm.c
@ -67,6 +67,8 @@ void run(const IRToks *ir, const BuiltinFunc *builtin_funcs) {
|
|||||||
case IREq:
|
case IREq:
|
||||||
case IRLt:
|
case IRLt:
|
||||||
case IRLe:
|
case IRLe:
|
||||||
|
case IRAnd:
|
||||||
|
case IROr:
|
||||||
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