Returning from functions
This commit is contained in:
@@ -14,6 +14,7 @@ typedef struct SolsVariable {
|
||||
typedef struct SolsScope {
|
||||
SolsVariable* variables;
|
||||
size_t tmpCounter;
|
||||
SolsType returnType;
|
||||
} SolsScope;
|
||||
|
||||
// Adds a variable to the SolsScope.
|
||||
|
||||
@@ -38,7 +38,8 @@ ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) {
|
||||
case SNT_PUTS:
|
||||
case SNT_IF:
|
||||
case SNT_WHILE:
|
||||
case SNT_CODE_BLOCK: {
|
||||
case SNT_CODE_BLOCK:
|
||||
case SNT_RETURN: {
|
||||
return Error(SolsType, charptr, "Specified node does not return data");
|
||||
}
|
||||
case SNT_OP_SET: {
|
||||
@@ -733,7 +734,8 @@ ResultType(GroundProgram, charptr) generateLambdaNode(SolsNode* node, SolsScope*
|
||||
// Lambdas do NOT have access to external state
|
||||
SolsScope lambdaScope = {
|
||||
.variables = NULL,
|
||||
.tmpCounter = 0
|
||||
.tmpCounter = 0,
|
||||
.returnType = *node->as.type.returnType
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < node->as.type.children.count; i++) {
|
||||
@@ -803,6 +805,9 @@ ResultType(GroundProgram, charptr) generateDefNode(SolsNode* node, SolsScope* sc
|
||||
// Create a scope for function arguments
|
||||
SolsScope functionScope = copySolsScope(scope);
|
||||
|
||||
// Set the scope's return type
|
||||
functionScope.returnType = *node->as.type.returnType;
|
||||
|
||||
for (size_t i = 0; i < node->as.type.children.count; i++) {
|
||||
addVariableToScope(&functionScope, node->as.type.children.at[i].name, node->as.type.children.at[i].type);
|
||||
}
|
||||
@@ -873,6 +878,30 @@ ResultType(GroundProgram, charptr) generateFunctionCallNode(SolsNode* node, Sols
|
||||
|
||||
}
|
||||
|
||||
ResultType(GroundProgram, charptr) generateReturnNode(SolsNode* node, SolsScope* scope) {
|
||||
if (node->children.count < 1) {
|
||||
return Error(GroundProgram, charptr, "Expecting a value in return");
|
||||
}
|
||||
|
||||
ResultType(SolsType, charptr) type = getNodeType(&node->children.at[0], scope);
|
||||
if (type.error) {
|
||||
return Error(GroundProgram, charptr, type.as.error);
|
||||
}
|
||||
|
||||
if (compareTypes(&type.as.success, &scope->returnType) == false) {
|
||||
return Error(GroundProgram, charptr, "Mismatched return type");
|
||||
}
|
||||
|
||||
GroundProgram program = groundCreateProgram();
|
||||
GroundInstruction inst = groundCreateInstruction(RETURN);
|
||||
|
||||
groundAddReferenceToInstruction(&inst, node->children.at[0].accessArg);
|
||||
|
||||
groundAddInstructionToProgram(&program, inst);
|
||||
|
||||
return Success(GroundProgram, charptr, program);
|
||||
}
|
||||
|
||||
ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope) {
|
||||
|
||||
GroundProgram program = groundCreateProgram();
|
||||
@@ -922,6 +951,7 @@ ResultType(GroundProgram, charptr) generateCode(SolsNode* node, SolsScope* scope
|
||||
case SNT_LAMBDA: generate(Lambda);
|
||||
case SNT_DEF: generate(Def);
|
||||
case SNT_FUNCTION_CALL: generate(FunctionCall);
|
||||
case SNT_RETURN: generate(Return);
|
||||
}
|
||||
return Success(GroundProgram, charptr, program);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "SolsLiteral.h"
|
||||
|
||||
typedef enum SolsTokenType {
|
||||
STT_IDENTIFIER, STT_LITERAL, STT_TYPE, STT_DOT, STT_OPEN_CURLY, STT_CLOSE_CURLY, STT_OPEN_PAREN, STT_CLOSE_PAREN, STT_OP_ADD, STT_OP_SUB, STT_OP_MUL, STT_OP_DIV, STT_OP_ADDTO, STT_OP_SUBTO, STT_OP_MULTO, STT_OP_DIVTO, STT_OP_INCREMENT, STT_OP_DECREMENT, STT_OP_SET, STT_OP_GREATER, STT_OP_LESSER, STT_OP_EQUAL, STT_OP_INEQUAL, STT_OP_EQGREATER, STT_OP_EQLESSER, STT_KW_DEF, STT_KW_LAMBDA, STT_KW_STRUCT, STT_KW_PUTS, STT_KW_IF, STT_KW_WHILE, STT_KW_NEW, STT_KW_GROUND, STT_LINE_END, STT_COMMA
|
||||
STT_IDENTIFIER, STT_LITERAL, STT_TYPE, STT_DOT, STT_OPEN_CURLY, STT_CLOSE_CURLY, STT_OPEN_PAREN, STT_CLOSE_PAREN, STT_OP_ADD, STT_OP_SUB, STT_OP_MUL, STT_OP_DIV, STT_OP_ADDTO, STT_OP_SUBTO, STT_OP_MULTO, STT_OP_DIVTO, STT_OP_INCREMENT, STT_OP_DECREMENT, STT_OP_SET, STT_OP_GREATER, STT_OP_LESSER, STT_OP_EQUAL, STT_OP_INEQUAL, STT_OP_EQGREATER, STT_OP_EQLESSER, STT_KW_DEF, STT_KW_LAMBDA, STT_KW_RETURN, STT_KW_STRUCT, STT_KW_PUTS, STT_KW_IF, STT_KW_WHILE, STT_KW_NEW, STT_KW_GROUND, STT_LINE_END, STT_COMMA
|
||||
} SolsTokenType;
|
||||
|
||||
typedef char* charptr;
|
||||
|
||||
@@ -12,6 +12,7 @@ struct _SolsTokenTypeMap SolsTokenTypeMap[] = {
|
||||
{"while", STT_KW_WHILE},
|
||||
{"def", STT_KW_DEF},
|
||||
{"lambda", STT_KW_LAMBDA},
|
||||
{"return", STT_KW_RETURN},
|
||||
{"struct", STT_KW_STRUCT},
|
||||
{"{", STT_OPEN_CURLY},
|
||||
{"}", STT_CLOSE_CURLY},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "lexer/SolsType.h"
|
||||
#include "lexer/lexer.h"
|
||||
#include "parser/parser.h"
|
||||
#include "codegen/codegen.h"
|
||||
@@ -87,7 +88,8 @@ int main(int argc, char** argv) {
|
||||
|
||||
SolsScope scope = {
|
||||
.variables = NULL,
|
||||
.tmpCounter = 0
|
||||
.tmpCounter = 0,
|
||||
.returnType = createSolsType(STT_INT).as.success
|
||||
};
|
||||
|
||||
// Do codegen on root node
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "../lexer/SolsToken.h"
|
||||
|
||||
typedef enum SolsNodeType {
|
||||
SNT_IDENTIFIER, SNT_LITERAL, SNT_TYPE, SNT_CODE_BLOCK, SNT_OP_ADD, SNT_OP_SUB, SNT_OP_MUL, SNT_OP_DIV, SNT_OP_ADDTO, SNT_OP_SUBTO, SNT_OP_MULTO, SNT_OP_DIVTO, SNT_OP_INCREMENT, SNT_OP_DECREMENT, SNT_OP_SET, SNT_OP_GREATER, SNT_OP_LESSER, SNT_OP_EQUAL, SNT_OP_INEQUAL, SNT_OP_EQGREATER, SNT_OP_EQLESSER, SNT_DEF, SNT_LAMBDA, SNT_FUNCTION_CALL, SNT_STRUCT, SNT_PUTS, SNT_IF, SNT_WHILE, SNT_NEW, SNT_GROUND, SNT_ROOT
|
||||
SNT_IDENTIFIER, SNT_LITERAL, SNT_TYPE, SNT_CODE_BLOCK, SNT_OP_ADD, SNT_OP_SUB, SNT_OP_MUL, SNT_OP_DIV, SNT_OP_ADDTO, SNT_OP_SUBTO, SNT_OP_MULTO, SNT_OP_DIVTO, SNT_OP_INCREMENT, SNT_OP_DECREMENT, SNT_OP_SET, SNT_OP_GREATER, SNT_OP_LESSER, SNT_OP_EQUAL, SNT_OP_INEQUAL, SNT_OP_EQGREATER, SNT_OP_EQLESSER, SNT_DEF, SNT_LAMBDA, SNT_FUNCTION_CALL, SNT_RETURN, SNT_STRUCT, SNT_PUTS, SNT_IF, SNT_WHILE, SNT_NEW, SNT_GROUND, SNT_ROOT
|
||||
} SolsNodeType;
|
||||
|
||||
struct SolsNode;
|
||||
|
||||
@@ -1507,6 +1507,55 @@ static inline ResultType(Nothing, charptr) parseFunctionCall(SolsParser* parser)
|
||||
return Success(Nothing, charptr, {});
|
||||
}
|
||||
|
||||
static inline ResultType(Nothing, charptr) parseReturn(SolsParser* parser) {
|
||||
|
||||
// Collect tokens for node
|
||||
ResultType(SolsTokens, charptr) tokens = createSolsTokens();
|
||||
if (tokens.error) {
|
||||
return Error(Nothing, charptr, tokens.as.error);
|
||||
}
|
||||
|
||||
ResultType(SolsToken, Nothing) peek = parserPeek(parser, 0);
|
||||
if (peek.error) return Error(Nothing, charptr, "ruh roh");
|
||||
|
||||
for (;;) {
|
||||
ResultType(SolsToken, Nothing) peek = parserPeek(parser, 1);
|
||||
if (peek.error) break;
|
||||
// Return and puts share the same high precedence
|
||||
if (getPrecedence(&peek.as.success) <= STP_PUTS) {
|
||||
break;
|
||||
}
|
||||
parserConsume(parser);
|
||||
addTokenToSolsTokens(&tokens.as.success, peek.as.success);
|
||||
}
|
||||
|
||||
// Create node
|
||||
ResultType(SolsNode, charptr) node = createSolsNode(SNT_RETURN);
|
||||
if (node.error) return Error(Nothing, charptr, node.as.error);
|
||||
node.as.success.line = peek.as.success.line;
|
||||
|
||||
// Parse selected tokens
|
||||
ResultType(SolsParser, charptr) returnParser = createSolsParser(&tokens.as.success);
|
||||
if (returnParser.error) return Error(Nothing, charptr, returnParser.as.error);
|
||||
returnParser.as.success.currentParent = &returnParser.as.success.output;
|
||||
ResultType(Nothing, charptr) parsed = parse(&returnParser.as.success);
|
||||
|
||||
// Add any error messages from parsing
|
||||
if (parsed.error) {
|
||||
addToParserErrors(parser, parsed.as.error);
|
||||
return Success(Nothing, charptr, {});
|
||||
}
|
||||
|
||||
// Copy nodes into the sols node
|
||||
for (size_t i = 0; i < returnParser.as.success.output.children.count; i++) {
|
||||
addChildToSolsNode(&node.as.success, returnParser.as.success.output.children.at[i]);
|
||||
}
|
||||
|
||||
addChildToSolsNode(parser->currentParent, node.as.success);
|
||||
|
||||
return Success(Nothing, charptr, {});
|
||||
}
|
||||
|
||||
static inline ResultType(Nothing, charptr) parseOpenParen(SolsParser* parser) {
|
||||
return Error(Nothing, charptr, "WIP");
|
||||
}
|
||||
@@ -1530,6 +1579,7 @@ ResultType(Nothing, charptr) parse(SolsParser* parser) {
|
||||
case STT_KW_IF: PARSER_HANDLE(If);
|
||||
case STT_KW_WHILE: PARSER_HANDLE(While);
|
||||
case STT_KW_LAMBDA: PARSER_HANDLE(Lambda);
|
||||
case STT_KW_RETURN: PARSER_HANDLE(Return);
|
||||
case STT_KW_DEF: PARSER_HANDLE(Def);
|
||||
case STT_OP_SET: PARSER_HANDLE(Set);
|
||||
case STT_OP_ADD: PARSER_HANDLE(Add);
|
||||
|
||||
Reference in New Issue
Block a user