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