Start work on lambda functions (WIP)

This commit is contained in:
2026-02-28 15:59:29 +11:00
parent cb0a1251c8
commit 92045c6bb9
5 changed files with 125 additions and 2 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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},

View File

@@ -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;

View File

@@ -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 (;;) {