mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
changed dot operator to access global functions
This commit is contained in:
@@ -309,7 +309,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
//special case for when indexing and assigning
|
||||
if (override != OP_EOF && node->binary.opcode >= OP_VAR_ASSIGN && node->binary.opcode <= OP_VAR_MODULO_ASSIGN) {
|
||||
writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override + 2; //1 byte WARNING: enum arithmetic
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override + 1; //1 byte WARNING: enum arithmetic
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)node->binary.opcode; //1 byte
|
||||
return OP_EOF;
|
||||
}
|
||||
@@ -319,7 +319,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
|
||||
//return from the index-binary
|
||||
//return this if...
|
||||
Opcode ret = writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
|
||||
//loopy logic - if opcode == index or dot
|
||||
@@ -504,7 +504,7 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
}
|
||||
|
||||
//push the argument COUNT to the top of the stack
|
||||
Literal argumentsCountLiteral = TO_INTEGER_LITERAL(node->fnCall.arguments->fnCollection.count);
|
||||
Literal argumentsCountLiteral = TO_INTEGER_LITERAL(node->fnCall.argumentCount); //argumentCount is set elsewhere to support dot operator
|
||||
int argumentsCountIndex = findLiteralIndex(&compiler->literalCache, argumentsCountLiteral);
|
||||
if (argumentsCountIndex < 0) {
|
||||
argumentsCountIndex = pushLiteralArray(&compiler->literalCache, argumentsCountLiteral);
|
||||
@@ -859,20 +859,8 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, Node* node, void* break
|
||||
break;
|
||||
|
||||
case NODE_DOT: {
|
||||
//pass to the child nodes, then embed the opcode
|
||||
if (!node->index.first) {
|
||||
writeLiteralToCompiler(compiler, TO_NULL_LITERAL);
|
||||
}
|
||||
else {
|
||||
Opcode override = writeCompilerWithJumps(compiler, node->index.first, breakAddressesPtr, continueAddressesPtr, jumpOffsets);
|
||||
if (override != OP_EOF) {//compensate for indexing & dot notation being screwy
|
||||
compiler->bytecode[compiler->count++] = (unsigned char)override; //1 byte
|
||||
}
|
||||
}
|
||||
|
||||
// compiler->bytecode[compiler->count++] = (unsigned char)OP_DOT; //1 byte
|
||||
|
||||
return OP_DOT_ASSIGN;
|
||||
fprintf(stderr, ERROR "[internal] NODE_DOT encountered in writeCompilerWithJumps()\n" RESET);
|
||||
compiler->bytecode[compiler->count++] = OP_EOF; //1 byte
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -990,7 +990,7 @@ static bool execFalseJump(Interpreter* interpreter) {
|
||||
static void execInterpreter(Interpreter*);
|
||||
static void readInterpreterSections(Interpreter* interpreter);
|
||||
|
||||
static bool execFnCall(Interpreter* interpreter) {
|
||||
static bool execFnCall(Interpreter* interpreter, bool looseFirstArgument) {
|
||||
//BUGFIX: depth check - don't drown!
|
||||
if (interpreter->depth >= 1000) {
|
||||
interpreter->errorOutput("Depth check failed\n");
|
||||
@@ -1004,7 +1004,14 @@ static bool execFnCall(Interpreter* interpreter) {
|
||||
Literal stackSize = popLiteralArray(&interpreter->stack);
|
||||
|
||||
//unpack the stack of arguments
|
||||
for (int i = 0; i < AS_INTEGER(stackSize); i++) {
|
||||
for (int i = 0; i < AS_INTEGER(stackSize) - 1; i++) {
|
||||
Literal lit = popLiteralArray(&interpreter->stack);
|
||||
pushLiteralArray(&arguments, lit); //NOTE: also reverses the order
|
||||
freeLiteral(lit);
|
||||
}
|
||||
|
||||
//collect one more argument
|
||||
if (!looseFirstArgument && AS_INTEGER(stackSize) > 0) {
|
||||
Literal lit = popLiteralArray(&interpreter->stack);
|
||||
pushLiteralArray(&arguments, lit); //NOTE: also reverses the order
|
||||
freeLiteral(lit);
|
||||
@@ -1012,6 +1019,23 @@ static bool execFnCall(Interpreter* interpreter) {
|
||||
|
||||
Literal identifier = popLiteralArray(&interpreter->stack);
|
||||
|
||||
//collect one more argument
|
||||
if (looseFirstArgument) {
|
||||
Literal lit = popLiteralArray(&interpreter->stack);
|
||||
pushLiteralArray(&arguments, lit); //NOTE: also reverses the order
|
||||
freeLiteral(lit);
|
||||
}
|
||||
|
||||
//let's screw with the fn name, too
|
||||
if (looseFirstArgument) {
|
||||
int length = strlen(AS_IDENTIFIER(identifier)) + 1;
|
||||
char buffer[MAX_STRING_LENGTH];
|
||||
snprintf(buffer, MAX_STRING_LENGTH, "_%s", AS_IDENTIFIER(identifier)); //prepend an underscore
|
||||
|
||||
freeLiteral(identifier);
|
||||
identifier = TO_IDENTIFIER_LITERAL(copyString(buffer, length), length);
|
||||
}
|
||||
|
||||
Literal func = identifier;
|
||||
|
||||
if (!parseIdentifierToValue(interpreter, &func)) {
|
||||
@@ -1453,81 +1477,6 @@ static bool execIndex(Interpreter* interpreter) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool execDot(Interpreter* interpreter) {
|
||||
//assume -> compound, first are all on the stack
|
||||
|
||||
Literal first = popLiteralArray(&interpreter->stack);
|
||||
Literal compound = popLiteralArray(&interpreter->stack);
|
||||
|
||||
Literal tmp = first;
|
||||
first = TO_STRING_LITERAL(copyString(AS_IDENTIFIER(tmp), strlen(AS_IDENTIFIER(tmp))) , strlen(AS_IDENTIFIER(tmp)) );
|
||||
freeLiteral(tmp);
|
||||
|
||||
if (!IS_IDENTIFIER(compound)) {
|
||||
interpreter->errorOutput("Unknown literal found in dot notation\n");
|
||||
printLiteralCustom(compound, interpreter->errorOutput);
|
||||
interpreter->errorOutput("\n");
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
return false;
|
||||
}
|
||||
|
||||
Literal idn = compound;
|
||||
|
||||
if (!parseIdentifierToValue(interpreter, &compound)) {
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IS_DICTIONARY(compound)) {
|
||||
interpreter->errorOutput("Unknown compound found in dot notation\n");
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
return false;
|
||||
}
|
||||
|
||||
//get the index function
|
||||
Literal func = TO_NULL_LITERAL;
|
||||
char* keyStr = "_dot";
|
||||
Literal key = TO_IDENTIFIER_LITERAL(copyString(keyStr, strlen(keyStr)), strlen(keyStr));
|
||||
|
||||
if (!getScopeVariable(interpreter->scope, key, &func) || !IS_FUNCTION_NATIVE(func)) {
|
||||
interpreter->errorOutput("couldn't get the _dot function\n");
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
freeLiteral(func);
|
||||
freeLiteral(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
//build the argument list
|
||||
LiteralArray arguments;
|
||||
initLiteralArray(&arguments);
|
||||
|
||||
pushLiteralArray(&arguments, compound);
|
||||
pushLiteralArray(&arguments, first);
|
||||
pushLiteralArray(&arguments, TO_NULL_LITERAL); //it expects an assignment command
|
||||
pushLiteralArray(&arguments, TO_NULL_LITERAL); //it expects an assignment "opcode"
|
||||
|
||||
//call the function
|
||||
NativeFn fn = (NativeFn)AS_FUNCTION(func).bytecode;
|
||||
fn(interpreter, &arguments);
|
||||
|
||||
//clean up
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
freeLiteral(func);
|
||||
freeLiteral(key);
|
||||
freeLiteralArray(&arguments);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool execIndexAssign(Interpreter* interpreter) {
|
||||
//assume -> compound, first, second, third, assign are all on the stack
|
||||
|
||||
@@ -1699,161 +1648,6 @@ static bool execIndexAssign(Interpreter* interpreter) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool execDotAssign(Interpreter* interpreter) {
|
||||
//assume -> compound, first, assign are all on the stack
|
||||
|
||||
Literal assign = popLiteralArray(&interpreter->stack);
|
||||
Literal first = popLiteralArray(&interpreter->stack);
|
||||
Literal compound = popLiteralArray(&interpreter->stack);
|
||||
|
||||
Literal tmp = first;
|
||||
first = TO_STRING_LITERAL(copyString(AS_IDENTIFIER(tmp), strlen(AS_IDENTIFIER(tmp))) , strlen(AS_IDENTIFIER(tmp)) );
|
||||
freeLiteral(tmp);
|
||||
|
||||
if (!IS_IDENTIFIER(compound)) {
|
||||
interpreter->errorOutput("Unknown literal found in dot assigning notation\n");
|
||||
printLiteralCustom(compound, interpreter->errorOutput);
|
||||
interpreter->errorOutput("\n");
|
||||
freeLiteral(assign);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
return false;
|
||||
}
|
||||
|
||||
Literal idn = compound;
|
||||
|
||||
if (!parseIdentifierToValue(interpreter, &compound)) {
|
||||
freeLiteral(assign);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IS_DICTIONARY(compound)) {
|
||||
interpreter->errorOutput("Unknown compound found in dot assigning notation\n");
|
||||
freeLiteral(assign);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
return false;
|
||||
}
|
||||
|
||||
//check const-ness of "first" within "compound"
|
||||
Literal type = getScopeType(interpreter->scope, idn);
|
||||
if (AS_TYPE(type).typeOf == LITERAL_DICTIONARY && AS_TYPE(((Literal*)(AS_TYPE(type).subtypes))[1]).constant) {
|
||||
interpreter->errorOutput("couldn't assign to constant within compound within dot assigning notation\n");
|
||||
freeLiteral(assign);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
freeLiteral(type);
|
||||
return false;
|
||||
}
|
||||
|
||||
//get the index function
|
||||
Literal func = TO_NULL_LITERAL;
|
||||
char* keyStr = "_dot";
|
||||
Literal key = TO_IDENTIFIER_LITERAL(copyString(keyStr, strlen(keyStr)), strlen(keyStr));
|
||||
|
||||
if (!getScopeVariable(interpreter->scope, key, &func) || !IS_FUNCTION_NATIVE(func)) {
|
||||
interpreter->errorOutput("couldn't get the _dot function\n");
|
||||
freeLiteral(assign);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
freeLiteral(func);
|
||||
freeLiteral(key);
|
||||
freeLiteral(type);
|
||||
return false;
|
||||
}
|
||||
|
||||
//build the opcode
|
||||
unsigned char opcode = readByte(interpreter->bytecode, &interpreter->count);
|
||||
char* opStr = "";
|
||||
switch(opcode) {
|
||||
case OP_VAR_ASSIGN:
|
||||
opStr = "=";
|
||||
break;
|
||||
case OP_VAR_ADDITION_ASSIGN:
|
||||
opStr = "+=";
|
||||
break;
|
||||
case OP_VAR_SUBTRACTION_ASSIGN:
|
||||
opStr = "-=";
|
||||
break;
|
||||
case OP_VAR_MULTIPLICATION_ASSIGN:
|
||||
opStr = "*=";
|
||||
break;
|
||||
case OP_VAR_DIVISION_ASSIGN:
|
||||
opStr = "/=";
|
||||
break;
|
||||
case OP_VAR_MODULO_ASSIGN:
|
||||
opStr = "%=";
|
||||
break;
|
||||
|
||||
default:
|
||||
interpreter->errorOutput("bad opcode in dot assigning notation\n");
|
||||
freeLiteral(assign);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
freeLiteral(func);
|
||||
freeLiteral(key);
|
||||
freeLiteral(type);
|
||||
return false;
|
||||
}
|
||||
|
||||
Literal op = TO_STRING_LITERAL(copyString(opStr, strlen(opStr)), strlen(opStr));
|
||||
|
||||
//build the argument list
|
||||
LiteralArray arguments;
|
||||
initLiteralArray(&arguments);
|
||||
|
||||
pushLiteralArray(&arguments, compound);
|
||||
pushLiteralArray(&arguments, first);
|
||||
pushLiteralArray(&arguments, assign); //it expects an assignment command
|
||||
pushLiteralArray(&arguments, op); //it expects an assignment "opcode"
|
||||
|
||||
//call the function
|
||||
NativeFn fn = (NativeFn)AS_FUNCTION(func).bytecode;
|
||||
fn(interpreter, &arguments);
|
||||
|
||||
//save the result (assume top of the interpreter stack is the new compound value)
|
||||
Literal result = popLiteralArray(&interpreter->stack);
|
||||
if (!setScopeVariable(interpreter->scope, idn, result, true)) {
|
||||
interpreter->errorOutput("Incorrect type assigned to compound member: ");
|
||||
printLiteralCustom(result, interpreter->errorOutput);
|
||||
interpreter->errorOutput("\n");
|
||||
|
||||
//clean up
|
||||
freeLiteral(assign);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
freeLiteral(func);
|
||||
freeLiteral(key);
|
||||
freeLiteral(type);
|
||||
freeLiteral(result);
|
||||
freeLiteralArray(&arguments);
|
||||
freeLiteral(op);
|
||||
return false;
|
||||
}
|
||||
|
||||
//clean up
|
||||
freeLiteral(op);
|
||||
freeLiteral(assign);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(idn);
|
||||
freeLiteral(func);
|
||||
freeLiteralArray(&arguments);
|
||||
freeLiteral(key);
|
||||
freeLiteral(type);
|
||||
freeLiteral(result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//the heart of toy
|
||||
static void execInterpreter(Interpreter* interpreter) {
|
||||
//set the starting point for the interpreter
|
||||
@@ -2038,11 +1832,18 @@ static void execInterpreter(Interpreter* interpreter) {
|
||||
break;
|
||||
|
||||
case OP_FN_CALL:
|
||||
if (!execFnCall(interpreter)) {
|
||||
if (!execFnCall(interpreter, false)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_DOT:
|
||||
if (!execFnCall(interpreter, true)) { //compensate for the out-of-order arguments
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case OP_FN_RETURN:
|
||||
if (!execFnReturn(interpreter)) {
|
||||
return;
|
||||
@@ -2067,24 +1868,12 @@ static void execInterpreter(Interpreter* interpreter) {
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_DOT:
|
||||
if (!execDot(interpreter)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_INDEX_ASSIGN:
|
||||
if (!execIndexAssign(interpreter)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_DOT_ASSIGN:
|
||||
if (!execDotAssign(interpreter)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_POP_STACK:
|
||||
while (interpreter->stack.count > 0) {
|
||||
freeLiteral(popLiteralArray(&interpreter->stack));
|
||||
@@ -2450,7 +2239,6 @@ void resetInterpreter(Interpreter* interpreter) {
|
||||
|
||||
//globally available functions
|
||||
injectNativeFn(interpreter, "_index", _index);
|
||||
injectNativeFn(interpreter, "_dot", _dot);
|
||||
injectNativeFn(interpreter, "_set", _set);
|
||||
injectNativeFn(interpreter, "_get", _get);
|
||||
injectNativeFn(interpreter, "_push", _push);
|
||||
|
||||
@@ -913,70 +913,6 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _dot(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
//_dot(compound, first, assignValue, opcode)
|
||||
Literal op = popLiteralArray(arguments);
|
||||
Literal assign = popLiteralArray(arguments);
|
||||
Literal first = popLiteralArray(arguments);
|
||||
Literal compound = popLiteralArray(arguments);
|
||||
|
||||
Literal value = getLiteralDictionary(AS_DICTIONARY(compound), first);
|
||||
|
||||
//dictionary
|
||||
if (IS_NULL(op)) {
|
||||
pushLiteralArray(&interpreter->stack, value);
|
||||
}
|
||||
|
||||
else if (!strcmp( AS_STRING(op), "=")) {
|
||||
setLiteralDictionary(AS_DICTIONARY(compound), first, assign);
|
||||
pushLiteralArray(&interpreter->stack, compound);
|
||||
}
|
||||
|
||||
else if (!strcmp( AS_STRING(op), "+=")) {
|
||||
Literal lit = addition(interpreter, value, assign);
|
||||
setLiteralDictionary(AS_DICTIONARY(compound), first, lit);
|
||||
freeLiteral(lit);
|
||||
pushLiteralArray(&interpreter->stack, compound);
|
||||
}
|
||||
|
||||
else if (!strcmp( AS_STRING(op), "-=")) {
|
||||
Literal lit = subtraction(interpreter, value, assign);
|
||||
setLiteralDictionary(AS_DICTIONARY(compound), first, lit);
|
||||
freeLiteral(lit);
|
||||
pushLiteralArray(&interpreter->stack, compound);
|
||||
}
|
||||
|
||||
else if (!strcmp( AS_STRING(op), "*=")) {
|
||||
Literal lit = multiplication(interpreter, value, assign);
|
||||
setLiteralDictionary(AS_DICTIONARY(compound), first, lit);
|
||||
freeLiteral(lit);
|
||||
pushLiteralArray(&interpreter->stack, compound);
|
||||
}
|
||||
|
||||
else if (!strcmp( AS_STRING(op), "/=")) {
|
||||
Literal lit = division(interpreter, value, assign);
|
||||
setLiteralDictionary(AS_DICTIONARY(compound), first, lit);
|
||||
freeLiteral(lit);
|
||||
pushLiteralArray(&interpreter->stack, compound);
|
||||
}
|
||||
|
||||
else if (!strcmp( AS_STRING(op), "%=")) {
|
||||
Literal lit = modulo(interpreter, value, assign);
|
||||
setLiteralDictionary(AS_DICTIONARY(compound), first, lit);
|
||||
freeLiteral(lit);
|
||||
pushLiteralArray(&interpreter->stack, compound);
|
||||
}
|
||||
|
||||
//cleanup
|
||||
freeLiteral(op);
|
||||
freeLiteral(assign);
|
||||
freeLiteral(first);
|
||||
freeLiteral(compound);
|
||||
freeLiteral(value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _set(Interpreter* interpreter, LiteralArray* arguments) {
|
||||
//if wrong number of arguments, fail
|
||||
if (arguments->count != 3) {
|
||||
|
||||
@@ -207,11 +207,12 @@ void emitNodeFnDecl(Node** nodeHandle, Literal identifier, Node* arguments, Node
|
||||
*nodeHandle = tmp;
|
||||
}
|
||||
|
||||
void emitFnCall(Node** nodeHandle, Node* arguments) {
|
||||
void emitFnCall(Node** nodeHandle, Node* arguments, int argumentCount) {
|
||||
Node* tmp = ALLOCATE(Node, 1);
|
||||
|
||||
tmp->type = NODE_FN_CALL;
|
||||
tmp->fnCall.arguments = arguments;
|
||||
tmp->fnCall.argumentCount = argumentCount;
|
||||
|
||||
*nodeHandle = tmp;
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ typedef struct NodeFnCollection {
|
||||
typedef struct NodeFnCall {
|
||||
NodeType type;
|
||||
Node* arguments;
|
||||
int argumentCount;
|
||||
} NodeFnCall;
|
||||
|
||||
typedef struct NodePath {
|
||||
@@ -162,7 +163,7 @@ void emitNodeCompound(Node** nodeHandle, LiteralType literalType);
|
||||
void setNodePair(Node* node, Node* left, Node* right);
|
||||
void emitNodeVarDecl(Node** nodeHandle, Literal identifier, Literal type, Node* expression);
|
||||
void emitNodeFnDecl(Node** nodeHandle, Literal identifier, Node* arguments, Node* returns, Node* block);
|
||||
void emitFnCall(Node** nodeHandle, Node* arguments);
|
||||
void emitFnCall(Node** nodeHandle, Node* arguments, int argumentCount);
|
||||
void emitNodeFnCollection(Node** nodeHandle);
|
||||
void emitNodePath(Node** nodeHandle, NodeType type, Node* preClause, Node* postClause, Node* condition, Node* thenPath, Node* elsePath);
|
||||
void emitNodePrefixIncrement(Node** nodeHandle, Literal identifier, int increment);
|
||||
|
||||
@@ -50,10 +50,8 @@ typedef enum Opcode {
|
||||
|
||||
//for indexing
|
||||
OP_INDEX,
|
||||
OP_DOT,
|
||||
|
||||
OP_INDEX_ASSIGN,
|
||||
OP_DOT_ASSIGN,
|
||||
OP_DOT,
|
||||
|
||||
//comparison of values
|
||||
OP_COMPARE_EQUAL,
|
||||
|
||||
@@ -677,7 +677,7 @@ static Opcode decrementInfix(Parser* parser, Node** nodeHandle) {
|
||||
}
|
||||
|
||||
static Opcode fnCall(Parser* parser, Node** nodeHandle) {
|
||||
advance(parser);
|
||||
advance(parser); //skip the left paren
|
||||
|
||||
//binary() is an infix rule - so only get the RHS of the operator
|
||||
switch(parser->previous.type) {
|
||||
@@ -708,7 +708,7 @@ static Opcode fnCall(Parser* parser, Node** nodeHandle) {
|
||||
}
|
||||
|
||||
//emit the call
|
||||
emitFnCall(nodeHandle, arguments);
|
||||
emitFnCall(nodeHandle, arguments, arguments->fnCollection.count);
|
||||
|
||||
return OP_FN_CALL;
|
||||
}
|
||||
@@ -786,14 +786,17 @@ static Opcode indexAccess(Parser* parser, Node** nodeHandle) {
|
||||
|
||||
static Opcode dot(Parser* parser, Node** nodeHandle) {
|
||||
advance(parser); //for the dot
|
||||
advance(parser); //for the identifier
|
||||
|
||||
Node* first = NULL;
|
||||
Node* node = NULL;
|
||||
|
||||
identifier(parser, &first); //specific case
|
||||
emitNodeDot(nodeHandle, first);
|
||||
parsePrecedence(parser, &node, PREC_CALL);
|
||||
|
||||
return OP_DOT;
|
||||
//hijack the function call, and hack in an extra parameter
|
||||
node->binary.right->fnCall.argumentCount++;
|
||||
node->binary.opcode = OP_DOT;
|
||||
|
||||
(*nodeHandle) = node;
|
||||
return OP_DOT; //signal that the function name and arguments are in the wrong order
|
||||
}
|
||||
|
||||
ParseRule parseRules[] = { //must match the token types
|
||||
|
||||
Reference in New Issue
Block a user