-> method call
This commit is contained in:
parent
5f3f61af2d
commit
ece31b11e0
|
@ -9,7 +9,7 @@ type
|
||||||
opClosure, # closures
|
opClosure, # closures
|
||||||
opPop, opPopSA, opPopA # pop
|
opPop, opPopSA, opPopA # pop
|
||||||
opNegate, opNot # unary
|
opNegate, opNot # unary
|
||||||
opSwap, # stack manipulation
|
opSwap, opDup, # stack manipulation
|
||||||
opAdd, opSubtract, opMultiply, opDivide, # math
|
opAdd, opSubtract, opMultiply, opDivide, # math
|
||||||
opEqual, opGreater, opLess, # comparison
|
opEqual, opGreater, opLess, # comparison
|
||||||
opTrue, opFalse, opNil, # literal
|
opTrue, opFalse, opNil, # literal
|
||||||
|
@ -92,7 +92,7 @@ proc writeConstant*(ch: var Chunk, constant: NdValue, line: int): int =
|
||||||
const simpleInstructions = {
|
const simpleInstructions = {
|
||||||
opReturn,
|
opReturn,
|
||||||
opPop,
|
opPop,
|
||||||
opSwap,
|
opSwap, opDup,
|
||||||
opNegate, opNot,
|
opNegate, opNot,
|
||||||
opAdd, opSubtract, opMultiply, opDivide,
|
opAdd, opSubtract, opMultiply, opDivide,
|
||||||
opEqual, opGreater, opLess,
|
opEqual, opGreater, opLess,
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
{.used.}
|
{.used.}
|
||||||
|
|
||||||
import strformat
|
import strformat
|
||||||
|
import bitops
|
||||||
|
|
||||||
import ../scanner
|
import ../scanner
|
||||||
import ../chunk
|
import ../chunk
|
||||||
|
import ../types/value
|
||||||
import ../config
|
import ../config
|
||||||
|
|
||||||
import types
|
import types
|
||||||
|
@ -67,6 +69,32 @@ proc parsePipeCall(comp: Compiler) =
|
||||||
|
|
||||||
tkDoublecolon.genRule(nop, parsePipeCall, pcAmpersand)
|
tkDoublecolon.genRule(nop, parsePipeCall, pcAmpersand)
|
||||||
|
|
||||||
|
proc parseArrowCall(comp: Compiler) =
|
||||||
|
# -> syntactic sugar for table "methods"
|
||||||
|
|
||||||
|
# when called, the stack contains the table
|
||||||
|
# the table should be duplicated first
|
||||||
|
comp.writeChunk(1, opDup)
|
||||||
|
# then the index should be read
|
||||||
|
comp.consume(tkIdentifier, "Identifier (index) expected after '->'.")
|
||||||
|
let index = comp.previous.text.fromNimString()
|
||||||
|
comp.writeConstant(index)
|
||||||
|
comp.writeChunk(-1, opGetIndex)
|
||||||
|
# the stack's state now is table, method
|
||||||
|
# invert to get the right alignment for further function call
|
||||||
|
comp.writeChunk(0, opSwap)
|
||||||
|
# now the same code as :: applies
|
||||||
|
var argcount = 1
|
||||||
|
# args optional
|
||||||
|
if comp.match(tkLeftParen):
|
||||||
|
argcount = 1 + comp.parseArgs()
|
||||||
|
|
||||||
|
comp.writeChunk(-argcount, opCall)
|
||||||
|
comp.writeChunk(0, argcount.uint8)
|
||||||
|
|
||||||
|
|
||||||
|
tkArrow.genRule(nop, parseArrowCall, pcIndex)
|
||||||
|
|
||||||
proc parseFunct(comp: Compiler) =
|
proc parseFunct(comp: Compiler) =
|
||||||
|
|
||||||
# jump over
|
# jump over
|
||||||
|
|
|
@ -11,7 +11,8 @@ type
|
||||||
|
|
||||||
TokenType* = enum
|
TokenType* = enum
|
||||||
tkNone, # the default tokentype, if encountered anywhere, erroring out is the best course of action
|
tkNone, # the default tokentype, if encountered anywhere, erroring out is the best course of action
|
||||||
tkLeftParen, tkRightParen, tkLeftBrace, tkRightBrace, tkComma, tkDot, tkColon, tkDoublecolon,
|
tkLeftParen, tkRightParen, tkLeftBrace, tkRightBrace, tkComma, tkDot,
|
||||||
|
tkColon, tkDoublecolon, tkArrow,
|
||||||
tkMinus, tkPlus, tkSemicolon, tkSlash, tkStar, tkBang, tkBangEqual,
|
tkMinus, tkPlus, tkSemicolon, tkSlash, tkStar, tkBang, tkBangEqual,
|
||||||
tkGreater, tkGreaterEqual, tkLess, tkLessEqual, tkEqual, tkEqualEqual,
|
tkGreater, tkGreaterEqual, tkLess, tkLessEqual, tkEqual, tkEqualEqual,
|
||||||
tkStartList, tkStartTable, tkLeftBracket, tkRightBracket,
|
tkStartList, tkStartTable, tkLeftBracket, tkRightBracket,
|
||||||
|
@ -127,7 +128,7 @@ const keywords = {
|
||||||
}.toTable
|
}.toTable
|
||||||
|
|
||||||
proc canStartIdent(chr: char): bool =
|
proc canStartIdent(chr: char): bool =
|
||||||
chr in Letters or chr in {'_', ':'}
|
chr in Letters or chr in {'_'}
|
||||||
|
|
||||||
proc canContIdent(chr: char): bool =
|
proc canContIdent(chr: char): bool =
|
||||||
canStartIdent(chr) or chr in Digits
|
canStartIdent(chr) or chr in Digits
|
||||||
|
@ -175,7 +176,11 @@ proc scanToken*(scanner: Scanner): Token =
|
||||||
of ';': return scanner.makeToken(tkSemicolon)
|
of ';': return scanner.makeToken(tkSemicolon)
|
||||||
of ',': return scanner.makeToken(tkComma)
|
of ',': return scanner.makeToken(tkComma)
|
||||||
of '.': return scanner.makeToken(tkDot)
|
of '.': return scanner.makeToken(tkDot)
|
||||||
of '-': return scanner.makeToken(tkMinus)
|
of '-':
|
||||||
|
if scanner.match('>'):
|
||||||
|
return scanner.makeToken(tkArrow)
|
||||||
|
else:
|
||||||
|
return scanner.makeToken(tkMinus)
|
||||||
of '+': return scanner.makeToken(tkPlus)
|
of '+': return scanner.makeToken(tkPlus)
|
||||||
of '/': return scanner.makeToken(tkSlash)
|
of '/': return scanner.makeToken(tkSlash)
|
||||||
of '*': return scanner.makeToken(tkStar)
|
of '*': return scanner.makeToken(tkStar)
|
||||||
|
@ -197,13 +202,13 @@ proc scanToken*(scanner: Scanner): Token =
|
||||||
if scanner.match('['): return scanner.makeToken(tkStartList)
|
if scanner.match('['): return scanner.makeToken(tkStartList)
|
||||||
elif scanner.match('{'): return scanner.makeToken(tkStartTable)
|
elif scanner.match('{'): return scanner.makeToken(tkStartTable)
|
||||||
else: return scanner.scanLabel()
|
else: return scanner.scanLabel()
|
||||||
|
of ':':
|
||||||
|
if scanner.match(':'): return scanner.makeToken(tkDoublecolon)
|
||||||
|
elif scanner.peek().canContIdent(): return scanner.scanIdentifier()
|
||||||
|
else: return scanner.makeToken(tkColon)
|
||||||
else:
|
else:
|
||||||
if c == ':' and scanner.match(':'):
|
|
||||||
return scanner.makeToken(tkDoublecolon)
|
|
||||||
if c.canStartIdent():
|
if c.canStartIdent():
|
||||||
# : can start ident, but if on its own it's probably syntactic sugar for tables
|
# ':' can start ident, but is not handled here
|
||||||
if c == ':' and not scanner.peek().canContIdent():
|
|
||||||
return scanner.makeToken(tkColon)
|
|
||||||
return scanner.scanIdentifier()
|
return scanner.scanIdentifier()
|
||||||
else:
|
else:
|
||||||
return scanner.errorToken("Unexpected character.")
|
return scanner.errorToken("Unexpected character.")
|
||||||
|
|
|
@ -188,6 +188,8 @@ proc run*(chunk: Chunk): InterpretResult =
|
||||||
stack.popn(amt)
|
stack.popn(amt)
|
||||||
of opSwap:
|
of opSwap:
|
||||||
stack.swap()
|
stack.swap()
|
||||||
|
of opDup:
|
||||||
|
stack.push(stack.peek())
|
||||||
of opConstant:
|
of opConstant:
|
||||||
let val: NdValue = ip.readConstant(chunk)
|
let val: NdValue = ip.readConstant(chunk)
|
||||||
stack.add(val)
|
stack.add(val)
|
||||||
|
|
|
@ -40,4 +40,44 @@ nested["lvl1"]["lvl2"]["lvl3"] = -5.4;
|
||||||
nested .lvl1 .lvl2 .lvl3 :: print;
|
nested .lvl1 .lvl2 .lvl3 :: print;
|
||||||
//expect:-5.4
|
//expect:-5.4
|
||||||
|
|
||||||
// creating tables with : and no [] idents
|
// creating tables with : and no [] idents
|
||||||
|
|
||||||
|
var mix = @{
|
||||||
|
ident = 5,
|
||||||
|
ident2: 6,
|
||||||
|
[3] = 7,
|
||||||
|
["ident4"]: 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
print(mix.ident, mix["ident2"], mix[3], mix.ident4);
|
||||||
|
//expect:5.0 6.0 7.0 8.0
|
||||||
|
|
||||||
|
// -> method call syntax
|
||||||
|
|
||||||
|
var class = @{
|
||||||
|
method = funct(self) print ("i was called")
|
||||||
|
};
|
||||||
|
|
||||||
|
// no args needed then no parentheses needed
|
||||||
|
class->method;
|
||||||
|
//expect:i was called
|
||||||
|
|
||||||
|
var multiplier = @{
|
||||||
|
multiple = 5,
|
||||||
|
do = funct(self, arg) :result = self.multiple * arg,
|
||||||
|
};
|
||||||
|
|
||||||
|
multiplier->do(7) :: print;
|
||||||
|
//expect:35.0
|
||||||
|
|
||||||
|
// -> method call syntax with :: - check for precedence
|
||||||
|
|
||||||
|
var returner = @{
|
||||||
|
method = funct(self) :result = funct(n) :result = n * 2
|
||||||
|
};
|
||||||
|
|
||||||
|
1.7 :: returner->method :: print;
|
||||||
|
//expect:3.4
|
||||||
|
|
||||||
|
print("finish");
|
||||||
|
//expect:finish
|
Loading…
Reference in New Issue