diff options
| -rw-r--r-- | chunk.d | 1 | ||||
| -rw-r--r-- | compiler.d | 18 | ||||
| -rw-r--r-- | parser.d | 28 | ||||
| -rw-r--r-- | vm.d | 5 |
4 files changed, 52 insertions, 0 deletions
@@ -139,6 +139,7 @@ enum OpCode { OP_ADD, OP_LESS, OP_NOT, + OP_EQUAL, OP_GREATER, OP_NEGATE, OP_RETURN, @@ -304,6 +304,20 @@ class Compiler { return ValueType.BOOLEAN; } + ValueType compileEq(Form[] args) { + if (args.length != 2) { + this.error(format("'eq?': expected [1] argument, received %d", to!int(args.length)), -1); + this.advance(); + return ValueType.NIL; + } + ValueType vt1 = this.resolve(args[0], ValueType.ANY); + ValueType vt2 = this.resolve(args[1], ValueType.ANY); + + this.func.chunk.writeOp(OpCode.OP_EQUAL, args[1].line); + + return ValueType.BOOLEAN; + } + //int parseVariable(Def def) { int parseVariable(Symbol sym) { @@ -726,6 +740,8 @@ class Compiler { return this.compileSubtract(cons.tail, ValueType.NUMBER); } break; + + // BOOLEAN case "<": return this.compileLess(cons.tail, ValueType.NUMBER); break; @@ -742,6 +758,8 @@ class Compiler { return vt; case "not": return this.compileNot(cons.tail); + case "eq?": + return this.compileEq(cons.tail); // STRINGS case "concat": @@ -320,6 +320,34 @@ struct Value { As as; } +bool areValuesEqual(Value left, Value right) { + if (left.type != right.type) { + return false; + } + + switch (left.type) { + case ValueType.NUMBER: + return left.as.number == right.as.number; + case ValueType.BOOLEAN: + return left.as.boolean == right.as.boolean; + case ValueType.SEQ: + Seq leftSeq = cast(Seq)left.as.seq; + Seq rightSeq = cast(Seq)right.as.seq; + if (leftSeq.type != rightSeq.type) { + return false; + } else if (leftSeq.type == SeqType.STRING) { + return (cast(String)leftSeq).str == (cast(String)rightSeq).str; + } else { + // NOTE if eq? should work for lists, that logic goes here + return false; + } + default: + writeln("!!! THIS VALUE TYPE IS NOT SUPPORTED BY eq?"); + return false; + } + +} + Value makeStringValue(string str) { As as = { str: str }; Value val = { ValueType.STRING, as }; @@ -447,6 +447,11 @@ class VM { bool bval = asBoolean(val); this.pushA(makeBooleanValue(!bval)); break; + case OpCode.OP_EQUAL: + Value b = this.popA(); + Value a = this.popA(); + this.pushA(makeBooleanValue(areValuesEqual(a, b))); + break; case OpCode.OP_CONCAT: Seq b = asSeq(this.popA()); Seq a = asSeq(this.popA()); |
