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",
|
||||
[IRLe] = "le",
|
||||
[IRNot] = "not",
|
||||
[IRAnd] = "and",
|
||||
[IROr] = "or",
|
||||
[IRJmp] = "jmp",
|
||||
[IRJnz] = "jnz",
|
||||
[IRCallInternal] = "calli",
|
||||
@ -119,6 +121,8 @@ void print_ir(IRToks *v, const BuiltinFunc *builtin_funcs) {
|
||||
case IREq:
|
||||
case IRLt:
|
||||
case IRLe:
|
||||
case IRAnd:
|
||||
case IROr:
|
||||
printf(" %%%zx ", v->toks[i].Binary.addr);
|
||||
print_irparam(&v->toks[i].Binary.lhs);
|
||||
printf(" ");
|
||||
|
2
ir.h
2
ir.h
@ -22,6 +22,8 @@ enum IRInstr {
|
||||
IRLt,
|
||||
IRLe,
|
||||
IRNot,
|
||||
IRAnd,
|
||||
IROr,
|
||||
IRJmp,
|
||||
IRJnz,
|
||||
IRCallInternal,
|
||||
|
14
lex.c
14
lex.c
@ -218,6 +218,20 @@ TokList lex(const char *s) {
|
||||
continue;
|
||||
}
|
||||
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 '(':
|
||||
|
4
parse.c
4
parse.c
@ -56,6 +56,8 @@ static void set_irtok_dest_addr(IRTok *t, size_t addr) {
|
||||
case IREq:
|
||||
case IRLt:
|
||||
case IRLe:
|
||||
case IRAnd:
|
||||
case IROr:
|
||||
t->Binary.addr = addr;
|
||||
break;
|
||||
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 OpGt: instr = IRLt; swap_operands = true; break;
|
||||
case OpGe: instr = IRLe; swap_operands = true; break;
|
||||
case OpAnd: instr = IRAnd; break;
|
||||
case OpOr: instr = IROr; break;
|
||||
default:
|
||||
mark_err(l_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,
|
||||
.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:
|
||||
ASSERT_UNREACHED();
|
||||
}
|
||||
|
22
tok.c
22
tok.c
@ -11,15 +11,17 @@ int8_t op_prec[OperatorEnumSize] = {
|
||||
[OpLCurl] = PREC_DELIM,
|
||||
[OpRParen] = PREC_DELIM,
|
||||
[OpComma] = PREC_DELIM,
|
||||
[OpEq] = 0,
|
||||
[OpLt] = 0,
|
||||
[OpGt] = 0,
|
||||
[OpLe] = 0,
|
||||
[OpGe] = 0,
|
||||
[OpAdd] = 1,
|
||||
[OpSub] = 1,
|
||||
[OpMul] = 2,
|
||||
[OpDiv] = 2,
|
||||
[OpAnd] = 0,
|
||||
[OpOr] = 0,
|
||||
[OpEq] = 1,
|
||||
[OpLt] = 1,
|
||||
[OpGt] = 1,
|
||||
[OpLe] = 1,
|
||||
[OpGe] = 1,
|
||||
[OpAdd] = 2,
|
||||
[OpSub] = 2,
|
||||
[OpMul] = 3,
|
||||
[OpDiv] = 3,
|
||||
};
|
||||
|
||||
const char *op_str[OperatorEnumSize] = {
|
||||
@ -40,6 +42,8 @@ const char *op_str[OperatorEnumSize] = {
|
||||
[OpGt] = ">",
|
||||
[OpLe] = "<=",
|
||||
[OpGe] = ">=",
|
||||
[OpAnd] = "&&",
|
||||
[OpOr] = "||",
|
||||
};
|
||||
|
||||
const char *tok_str[TokKindEnumSize] = {
|
||||
|
2
tok.h
2
tok.h
@ -47,6 +47,8 @@ enum Operator {
|
||||
OpGt,
|
||||
OpLe,
|
||||
OpGe,
|
||||
OpAnd,
|
||||
OpOr,
|
||||
OpNewLn,
|
||||
OpEOF,
|
||||
OperatorEnumSize,
|
||||
|
Loading…
Reference in New Issue
Block a user