add 'not equal' operator
This commit is contained in:
parent
1f47b5e16c
commit
18d6e7b7df
2
ir.c
2
ir.c
@ -11,6 +11,7 @@ const char *irinstr_str[IRInstrEnumSize] = {
|
||||
[IRMul] = "mul",
|
||||
[IRDiv] = "div",
|
||||
[IREq] = "eq",
|
||||
[IRNeq] = "neq",
|
||||
[IRLt] = "lt",
|
||||
[IRLe] = "le",
|
||||
[IRNot] = "not",
|
||||
@ -98,6 +99,7 @@ void print_ir(IRToks *v, const BuiltinFunc *builtin_funcs) {
|
||||
case IRDiv:
|
||||
case IRMul:
|
||||
case IREq:
|
||||
case IRNeq:
|
||||
case IRLt:
|
||||
case IRLe:
|
||||
case IRAnd:
|
||||
|
18
lex.c
18
lex.c
@ -222,18 +222,27 @@ TokList lex(const char *s, Pool *static_vars) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case '!':
|
||||
consume(&pos, *(s++));
|
||||
if (s[0] == '=')
|
||||
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpNeq, });
|
||||
else {
|
||||
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpNot, });
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case '&':
|
||||
consume(&pos, *(s++));
|
||||
if (s[0] == '&') {
|
||||
if (s[0] == '&')
|
||||
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpAnd });
|
||||
} else
|
||||
else
|
||||
continue;
|
||||
break;
|
||||
case '|':
|
||||
consume(&pos, *(s++));
|
||||
if (s[0] == '|') {
|
||||
if (s[0] == '|')
|
||||
emit(&toks, &pos, (Tok){ .kind = TokOp, .Op = OpOr });
|
||||
} else
|
||||
else
|
||||
continue;
|
||||
break;
|
||||
case '{':
|
||||
@ -244,7 +253,6 @@ TokList lex(const char *s, Pool *static_vars) {
|
||||
case '+':
|
||||
case '-':
|
||||
case '*':
|
||||
case '!':
|
||||
emit(&toks, &pos, (Tok){
|
||||
.kind = TokOp,
|
||||
.Op = s[0],
|
||||
|
2
parse.c
2
parse.c
@ -54,6 +54,7 @@ static void set_irtok_dest_addr(IRTok *t, size_t addr) {
|
||||
case IRMul:
|
||||
case IRDiv:
|
||||
case IREq:
|
||||
case IRNeq:
|
||||
case IRLt:
|
||||
case IRLe:
|
||||
case IRAnd:
|
||||
@ -457,6 +458,7 @@ static ExprRet expr(IRToks *out_ir, TokList *toks, Map *funcs, Scope *parent_sc,
|
||||
case OpMul: instr = IRMul; break;
|
||||
case OpDiv: instr = IRDiv; break;
|
||||
case OpEq: instr = IREq; break;
|
||||
case OpNeq: instr = IRNeq; break;
|
||||
case OpLt: instr = IRLt; break;
|
||||
case OpLe: instr = IRLe; break;
|
||||
case OpGt: instr = IRLt; swap_operands = true; break;
|
||||
|
18
runtime.c
18
runtime.c
@ -40,21 +40,24 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
|
||||
}
|
||||
}
|
||||
case IREq:
|
||||
case IRNeq:
|
||||
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;
|
||||
case IREq: res = lhs->Int == rhs->Int; break;
|
||||
case IRNeq: 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;
|
||||
case IREq: res = lhs->Float == rhs->Float; break;
|
||||
case IRNeq: 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 if (lhs->type.kind == TypeArr && lhs->Arr.type.kind == TypeChar && lhs->Arr.is_string &&
|
||||
@ -63,6 +66,9 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
|
||||
case IREq:
|
||||
res = lhs->Arr.len == rhs->Arr.len ? strncmp(lhs->Arr.vals, rhs->Arr.vals, lhs->Arr.len) == 0 : false;
|
||||
break;
|
||||
case IRNeq:
|
||||
res = lhs->Arr.len == rhs->Arr.len ? strncmp(lhs->Arr.vals, rhs->Arr.vals, lhs->Arr.len) != 0 : true;
|
||||
break;
|
||||
default:
|
||||
set_err("String operation '%s' not supported", irinstr_str[instr]);
|
||||
break;
|
||||
|
2
tok.c
2
tok.c
@ -92,6 +92,7 @@ int8_t op_prec[OperatorEnumSize] = {
|
||||
[OpAnd] = 0,
|
||||
[OpOr] = 0,
|
||||
[OpEq] = 1,
|
||||
[OpNeq] = 1,
|
||||
[OpLt] = 1,
|
||||
[OpGt] = 1,
|
||||
[OpLe] = 1,
|
||||
@ -116,6 +117,7 @@ const char *op_str[OperatorEnumSize] = {
|
||||
[OpNewLn] = "\\n",
|
||||
[OpEOF] = "EOF",
|
||||
[OpEq] = "==",
|
||||
[OpNeq] = "!=",
|
||||
[OpLt] = "<",
|
||||
[OpGt] = ">",
|
||||
[OpLe] = "<=",
|
||||
|
1
tok.h
1
tok.h
@ -57,6 +57,7 @@ enum Operator {
|
||||
OpNot = '!',
|
||||
OpBeginNonchars = 256,
|
||||
OpEq,
|
||||
OpNeq,
|
||||
OpLt,
|
||||
OpGt,
|
||||
OpLe,
|
||||
|
Loading…
Reference in New Issue
Block a user