add 'not equal' operator

This commit is contained in:
r4 2021-12-26 12:19:54 +01:00
parent 1f47b5e16c
commit 18d6e7b7df
8 changed files with 34 additions and 11 deletions

2
ir.c
View File

@ -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:

1
ir.h
View File

@ -19,6 +19,7 @@ enum IRInstr {
IRMul,
IRDiv,
IREq,
IRNeq,
IRLt,
IRLe,
IRNot,

18
lex.c
View File

@ -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],

View File

@ -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;

View File

@ -40,12 +40,14 @@ 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 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();
@ -53,6 +55,7 @@ Value eval_binary(IRInstr instr, const Value *lhs, const Value *rhs) {
} else if (lhs->type.kind == TypeFloat && rhs->type.kind == TypeFloat) {
switch (instr) {
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();
@ -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
View File

@ -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
View File

@ -57,6 +57,7 @@ enum Operator {
OpNot = '!',
OpBeginNonchars = 256,
OpEq,
OpNeq,
OpLt,
OpGt,
OpLe,

1
vm.c
View File

@ -65,6 +65,7 @@ void run(const IRToks *ir, const BuiltinFunc *builtin_funcs) {
case IRDiv:
case IRMul:
case IREq:
case IRNeq:
case IRLt:
case IRLe:
case IRAnd: