Added support for string literals and related operations

This commit is contained in:
nocturn9x 2020-08-14 08:25:05 +02:00
parent 3fe0660b32
commit b8ea713312
6 changed files with 44 additions and 10 deletions

1
nim/.gitignore vendored
View File

@ -1 +0,0 @@
main

View File

@ -4,7 +4,7 @@ import meta/chunk
import meta/tokenobject
import meta/valueobject
import meta/tokentype
import types/objecttype
type
@ -183,8 +183,8 @@ proc unary(self: Compiler) =
return
proc str(self: Compiler) =
return
proc strVal(self: Compiler) =
self.emitConstant(Value(kind: OBJECT, obj: Obj(kind: STRING, str: self.parser.previous().lexeme)))
proc bracket(self: Compiler) =
@ -202,9 +202,6 @@ proc literal(self: Compiler) =
else:
discard # Unreachable
proc strVal(self: Compiler) =
return
proc number(self: Compiler) =
var value = self.parser.previous().literal

View File

@ -95,7 +95,7 @@ proc parseString(self: var Lexer, delimiter: char) =
echo &"SyntaxError: Unterminated string literal at line {self.line}"
self.errored = true
discard self.step()
let value = Value(kind: ValueTypes.OBJECT, obj: Obj(kind: ObjectTypes.STRING, str: self.source[self.start..<self.current - 1])) # Get the value between quotes
let value = Value(kind: ValueTypes.OBJECT, obj: Obj(kind: ObjectTypes.STRING, str: self.source[self.start..<self.current])) # Get the value between quotes
let token = self.createToken(STR, value)
self.tokens.add(token)

View File

@ -49,6 +49,10 @@ proc isNum*(value: Value): bool =
return isInt(value) or isFloat(value)
proc isObj*(value: Value): bool =
return value.kind == OBJECT
proc toBool*(value: Value): bool =
return value.boolValue

View File

@ -18,6 +18,10 @@ proc isFalsey*(obj: Obj): bool =
return false
proc objType*(obj: Obj): ObjectTypes =
return obj.kind
proc stringify*(obj: Obj): string =
case obj.kind:
of STRING:

View File

@ -44,6 +44,10 @@ proc push*(self: VM, value: Value) =
self.stackTop = self.stackTop + 1
proc peek*(self: VM, distance: int): Value =
return self.stack[len(self.stack) - distance - 1]
proc run(self: VM, debug: bool): InterpretResult =
template readByte: untyped =
inc(self.ip)
@ -121,13 +125,39 @@ proc run(self: VM, debug: bool): InterpretResult =
echo &"Unsupported unary operator '-' for object of type '{toLowerAscii($cur.kind)}'"
return RUNTIME_ERROR
of OP_ADD:
BinOp(`+`, isNum)
if self.peek(0).kind == OBJECT and self.peek(1).kind == OBJECT:
if self.peek(0).obj.kind == STRING and self.peek(1).obj.kind == STRING:
var r = self.peek(0).obj.str
var l = self.peek(1).obj.str
self.push(Value(kind: OBJECT, obj: Obj(kind: STRING, str: l[0..len(l) - 2] & r[1..<len(r)])))
else:
self.error(newTypeError(&"Unsupported binary operand for objects of type '{toLowerAscii($(self.peek(0).kind))}' and '{toLowerAscii($(self.peek(1).kind))}'"))
return RUNTIME_ERROR
else:
BinOp(`+`, isNum)
of OP_SUBTRACT:
BinOp(`-`, isNum)
of OP_DIVIDE:
BinOp(`/`, isNum)
of OP_MULTIPLY:
BinOp(`*`, isNum)
if self.peek(0).kind == INTEGER and self.peek(1).kind == OBJECT:
if self.peek(1).obj.kind == STRING:
var r = self.peek(0).intValue
var l = self.peek(1).obj.str
self.push(Value(kind: OBJECT, obj: Obj(kind: STRING, str: l[0] & l[1..len(l) - 2].repeat(r) & l[len(l) - 1])))
else:
self.error(newTypeError(&"Unsupported binary operand for objects of type '{toLowerAscii($(self.peek(0).kind))}' and '{toLowerAscii($(self.peek(1).kind))}'"))
return RUNTIME_ERROR
elif self.peek(0).kind == OBJECT and self.peek(1).kind == INTEGER:
if self.peek(0).obj.kind == STRING:
var r = self.peek(0).obj.str
var l = self.peek(1).intValue
self.push(Value(kind: OBJECT, obj: Obj(kind: STRING, str: r[0] & r[1..len(r) - 2].repeat(l) & r[len(r) - 1])))
else:
self.error(newTypeError(&"Unsupported binary operand for objects of type '{toLowerAscii($(self.peek(0).kind))}' and '{toLowerAscii($(self.peek(1).kind))}'"))
return RUNTIME_ERROR
else:
BinOp(`*`, isNum)
of OP_MOD:
BinOp(floorMod, isNum)
of OP_POW: