mirror of https://github.com/japl-lang/japl.git
Added support for string literals and related operations
This commit is contained in:
parent
3fe0660b32
commit
b8ea713312
|
@ -1 +0,0 @@
|
|||
main
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
34
nim/vm.nim
34
nim/vm.nim
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue