Start work on lambda functions (WIP)
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
#include "SolsLiteral.h"
|
#include "SolsLiteral.h"
|
||||||
|
|
||||||
typedef enum SolsTokenType {
|
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_STRUCT, STT_KW_PUTS, STT_KW_IF, STT_KW_WHILE, STT_KW_NEW, STT_KW_GROUND, STT_LINE_END
|
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
|
||||||
} SolsTokenType;
|
} SolsTokenType;
|
||||||
|
|
||||||
typedef char* charptr;
|
typedef char* charptr;
|
||||||
|
|||||||
@@ -48,6 +48,14 @@ struct SolsTypeField;
|
|||||||
//
|
//
|
||||||
typedef struct SolsType {
|
typedef struct SolsType {
|
||||||
SolsTypeType type;
|
SolsTypeType type;
|
||||||
|
|
||||||
|
// For use when type is identified with a name
|
||||||
|
char* identifierType;
|
||||||
|
|
||||||
|
// For use in functions
|
||||||
|
struct SolsType* returnType;
|
||||||
|
|
||||||
|
// For use by fun, template, object
|
||||||
struct {
|
struct {
|
||||||
struct SolsTypeField* at;
|
struct SolsTypeField* at;
|
||||||
size_t count;
|
size_t count;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ struct _SolsTokenTypeMap SolsTokenTypeMap[] = {
|
|||||||
{"if", STT_KW_IF},
|
{"if", STT_KW_IF},
|
||||||
{"while", STT_KW_WHILE},
|
{"while", STT_KW_WHILE},
|
||||||
{"def", STT_KW_DEF},
|
{"def", STT_KW_DEF},
|
||||||
|
{"lambda", STT_KW_LAMBDA},
|
||||||
{"struct", STT_KW_STRUCT},
|
{"struct", STT_KW_STRUCT},
|
||||||
{"{", STT_OPEN_CURLY},
|
{"{", STT_OPEN_CURLY},
|
||||||
{"}", STT_CLOSE_CURLY},
|
{"}", STT_CLOSE_CURLY},
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "../lexer/SolsToken.h"
|
#include "../lexer/SolsToken.h"
|
||||||
|
|
||||||
typedef enum SolsNodeType {
|
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_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_STRUCT, SNT_PUTS, SNT_IF, SNT_WHILE, SNT_NEW, SNT_GROUND, SNT_ROOT
|
||||||
} SolsNodeType;
|
} SolsNodeType;
|
||||||
|
|
||||||
struct SolsNode;
|
struct SolsNode;
|
||||||
|
|||||||
@@ -1129,6 +1129,120 @@ static inline ResultType(Nothing, charptr) parseCloseCurly(SolsParser* parser) {
|
|||||||
return Error(Nothing, charptr, "Extra closing curly brace");
|
return Error(Nothing, charptr, "Extra closing curly brace");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline ResultType(Nothing, charptr) parseLambda(SolsParser* parser) {
|
||||||
|
ResultType(SolsToken, Nothing) openBracket = parserConsume(parser);
|
||||||
|
if (openBracket.error || openBracket.as.success.type != STT_OPEN_PAREN) {
|
||||||
|
return Error(Nothing, charptr, "Expecting '(' after 'lambda'");
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(SolsType, charptr) type = createSolsType(STT_FUN);
|
||||||
|
if (type.error) {
|
||||||
|
return Error(Nothing, charptr, type.as.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultType(SolsNode, charptr) node = createSolsNode(SNT_LAMBDA);
|
||||||
|
if (node.error) {
|
||||||
|
return Error(Nothing, charptr, node.as.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse type signature
|
||||||
|
for (;;) {
|
||||||
|
ResultType(SolsToken, Nothing) next = parserPeek(parser, 1);
|
||||||
|
if (next.error) {
|
||||||
|
return Error(Nothing, charptr, "Expecting ')' at end of lambda argument list");
|
||||||
|
}
|
||||||
|
if (next.as.success.type == STT_CLOSE_PAREN) {
|
||||||
|
parserConsume(parser);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.error) {
|
||||||
|
return Error(Nothing, charptr, type.as.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pattern of type, name
|
||||||
|
|
||||||
|
SolsType tmpType;
|
||||||
|
|
||||||
|
if (next.as.success.type == STT_TYPE) {
|
||||||
|
tmpType = next.as.success.as.type;
|
||||||
|
} else if (next.as.success.type == STT_IDENTIFIER) {
|
||||||
|
tmpType.identifierType = next.as.success.as.idName;
|
||||||
|
} else {
|
||||||
|
return Error(Nothing, charptr, "Expecting a type or identifier of type in lambda argument list");
|
||||||
|
}
|
||||||
|
|
||||||
|
parserConsume(parser);
|
||||||
|
|
||||||
|
char* argName;
|
||||||
|
next = parserPeek(parser, 1);
|
||||||
|
|
||||||
|
if (next.as.success.type == STT_IDENTIFIER) {
|
||||||
|
argName = next.as.success.as.idName;
|
||||||
|
} else {
|
||||||
|
return Error(Nothing, charptr, "Expecting identifier after type in lambda argument list");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add type to constructed SolsType
|
||||||
|
addChildToSolsType(&type.as.success, tmpType, argName);
|
||||||
|
parserConsume(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse type at the end
|
||||||
|
ResultType(SolsToken, Nothing) retType = parserPeek(parser, 1);
|
||||||
|
if (retType.error) {
|
||||||
|
return Error(Nothing, charptr, "Expecting return type or identifier of type after lambda argument list");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retType.as.success.type == STT_TYPE) {
|
||||||
|
type.as.success.returnType = malloc(sizeof(SolsType));
|
||||||
|
if (type.as.success.returnType == NULL) {
|
||||||
|
return Error(Nothing, charptr, "Failed to allocate memory for type");
|
||||||
|
}
|
||||||
|
*type.as.success.returnType = retType.as.success.as.type;
|
||||||
|
} else if (retType.as.success.type == STT_IDENTIFIER) {
|
||||||
|
type.as.success.returnType = malloc(sizeof(SolsType));
|
||||||
|
if (type.as.success.returnType == NULL) {
|
||||||
|
return Error(Nothing, charptr, "Failed to allocate memory for type");
|
||||||
|
}
|
||||||
|
type.as.success.returnType->identifierType = retType.as.success.as.idName;
|
||||||
|
} else {
|
||||||
|
return Error(Nothing, charptr, "Expecting return type or identifier of type after lambda argument list");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add type to node
|
||||||
|
node.as.success.as.type = type.as.success;
|
||||||
|
|
||||||
|
parserConsume(parser); // Consumes return type
|
||||||
|
|
||||||
|
// Skip newlines before the opening curly brace
|
||||||
|
while (parserPeek(parser, 1).as.success.type == STT_LINE_END) {
|
||||||
|
parserConsume(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parserPeek(parser, 1).as.success.type != STT_OPEN_CURLY) {
|
||||||
|
return Error(Nothing, charptr, "Expecting opening curly brace ({) for lambda body");
|
||||||
|
}
|
||||||
|
parserConsume(parser); // Consumes {
|
||||||
|
|
||||||
|
// Add node to parent
|
||||||
|
addChildToSolsNode(parser->currentParent, node.as.success);
|
||||||
|
|
||||||
|
// Parse code block
|
||||||
|
ResultType(Nothing, charptr) res = parseCodeBlock(parser);
|
||||||
|
if(res.error) return res;
|
||||||
|
|
||||||
|
// Last child of parent is code block, we need to move it
|
||||||
|
SolsNode codeBlock = parser->currentParent->children.at[parser->currentParent->children.count - 1];
|
||||||
|
parser->currentParent->children.count--;
|
||||||
|
|
||||||
|
// We need to get the actual node from the parent to modify it
|
||||||
|
SolsNode* lambdaNode = &parser->currentParent->children.at[parser->currentParent->children.count - 1];
|
||||||
|
addChildToSolsNode(lambdaNode, codeBlock);
|
||||||
|
|
||||||
|
return Success(Nothing, charptr, {});
|
||||||
|
}
|
||||||
|
|
||||||
ResultType(Nothing, charptr) parse(SolsParser* parser) {
|
ResultType(Nothing, charptr) parse(SolsParser* parser) {
|
||||||
parser->currentParent = &parser->output;
|
parser->currentParent = &parser->output;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|||||||
Reference in New Issue
Block a user