Functions are WIP, read more

They're no-ops in compilation for now, and param types aren't parsed.

'return' keyword needs to be implemented.

Was distracted by bugfixes in v2 and v2-docs.
This commit is contained in:
2025-02-02 17:26:47 +11:00
parent 336616a1bf
commit b93ea5006c
6 changed files with 76 additions and 9 deletions

13
scripts/funky.toy Normal file
View File

@@ -0,0 +1,13 @@
fn name(param1, param2) {
//return 42;
}
/*
fn name(param1: int, param2: float) {
return 42;
}
*/

View File

@@ -202,6 +202,17 @@ void Toy_private_emitAstVariableAccess(Toy_Bucket** bucketHandle, Toy_Ast** astH
(*astHandle) = tmp; (*astHandle) = tmp;
} }
void Toy_private_emitAstFunctionDeclaration(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_String* name, Toy_Ast* params, Toy_Ast* body) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));
tmp->type = TOY_AST_FN_DECLARE;
tmp->fnDeclare.name = name;
tmp->fnDeclare.params = params;
tmp->fnDeclare.body = body;
(*astHandle) = tmp;
}
void Toy_private_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) { void Toy_private_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle) {
Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast)); Toy_Ast* tmp = (Toy_Ast*)Toy_partitionBucket(bucketHandle, sizeof(Toy_Ast));

View File

@@ -30,6 +30,8 @@ typedef enum Toy_AstType {
TOY_AST_VAR_ASSIGN, TOY_AST_VAR_ASSIGN,
TOY_AST_VAR_ACCESS, TOY_AST_VAR_ACCESS,
TOY_AST_FN_DECLARE,
TOY_AST_PASS, TOY_AST_PASS,
TOY_AST_ERROR, TOY_AST_ERROR,
TOY_AST_END, TOY_AST_END,
@@ -191,6 +193,13 @@ typedef struct Toy_AstVarAccess {
Toy_Ast* child; Toy_Ast* child;
} Toy_AstVarAccess; } Toy_AstVarAccess;
typedef struct Toy_AstFnDeclare {
Toy_AstType type;
Toy_String* name;
Toy_Ast* params;
Toy_Ast* body;
} Toy_AstFnDeclare;
typedef struct Toy_AstPass { typedef struct Toy_AstPass {
Toy_AstType type; Toy_AstType type;
} Toy_AstPass; } Toy_AstPass;
@@ -223,6 +232,7 @@ union Toy_Ast { //see 'test_ast.c' for bitness tests
Toy_AstVarDeclare varDeclare; Toy_AstVarDeclare varDeclare;
Toy_AstVarAssign varAssign; Toy_AstVarAssign varAssign;
Toy_AstVarAccess varAccess; Toy_AstVarAccess varAccess;
Toy_AstFnDeclare fnDeclare;
Toy_AstPass pass; Toy_AstPass pass;
Toy_AstError error; Toy_AstError error;
Toy_AstEnd end; Toy_AstEnd end;
@@ -251,6 +261,8 @@ void Toy_private_emitAstVariableDeclaration(Toy_Bucket** bucketHandle, Toy_Ast**
void Toy_private_emitAstVariableAssignment(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_AstFlag flag, Toy_Ast* expr); void Toy_private_emitAstVariableAssignment(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_AstFlag flag, Toy_Ast* expr);
void Toy_private_emitAstVariableAccess(Toy_Bucket** bucketHandle, Toy_Ast** astHandle); void Toy_private_emitAstVariableAccess(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_emitAstFunctionDeclaration(Toy_Bucket** bucketHandle, Toy_Ast** astHandle, Toy_String* name, Toy_Ast* params, Toy_Ast* body);
void Toy_private_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle); void Toy_private_emitAstPass(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_emitAstError(Toy_Bucket** bucketHandle, Toy_Ast** astHandle); void Toy_private_emitAstError(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);
void Toy_private_emitAstEnd(Toy_Bucket** bucketHandle, Toy_Ast** astHandle); void Toy_private_emitAstEnd(Toy_Bucket** bucketHandle, Toy_Ast** astHandle);

View File

@@ -899,10 +899,11 @@ static unsigned int writeInstructionAccess(Toy_ModuleBuilder** mb, Toy_AstVarAcc
return 1; return 1;
} }
//routine structure static unsigned int writeInstructionFnDeclare(Toy_ModuleBuilder** mb, Toy_AstFnDeclare ast) {
// static void writeModuleBuilderParam(Toy_ModuleBuilder* mb) { (void)mb;
// // (void)ast;
// } return 0;
}
static unsigned int writeModuleBuilderCode(Toy_ModuleBuilder** mb, Toy_Ast* ast) { static unsigned int writeModuleBuilderCode(Toy_ModuleBuilder** mb, Toy_Ast* ast) {
if (ast == NULL) { if (ast == NULL) {
@@ -1010,6 +1011,10 @@ static unsigned int writeModuleBuilderCode(Toy_ModuleBuilder** mb, Toy_Ast* ast)
result += writeInstructionAccess(mb, ast->varAccess); result += writeInstructionAccess(mb, ast->varAccess);
break; break;
case TOY_AST_FN_DECLARE:
result += writeInstructionFnDeclare(mb, ast->fnDeclare);
break;
case TOY_AST_PASS: case TOY_AST_PASS:
//NO-OP //NO-OP
break; break;

View File

@@ -890,7 +890,7 @@ static void makeVariableDeclarationStmt(Toy_Bucket** bucketHandle, Toy_Parser* p
} }
} }
//build the string //build the name string
Toy_String* nameStr = Toy_createNameStringLength(bucketHandle, nameToken.lexeme, nameToken.length, varType, constant); Toy_String* nameStr = Toy_createNameStringLength(bucketHandle, nameToken.lexeme, nameToken.length, varType, constant);
//if there's an assignment, read it, or default to null //if there's an assignment, read it, or default to null
@@ -908,6 +908,31 @@ static void makeVariableDeclarationStmt(Toy_Bucket** bucketHandle, Toy_Parser* p
consume(parser, TOY_TOKEN_OPERATOR_SEMICOLON, "Expected ';' at the end of var statement"); consume(parser, TOY_TOKEN_OPERATOR_SEMICOLON, "Expected ';' at the end of var statement");
} }
static void makeFunctionDeclarationStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
consume(parser, TOY_TOKEN_NAME, "Expected function name after 'fn' keyword");
if (parser->previous.length > 255) {
printError(parser, parser->previous, "Can't have a function name longer than 255 characters");
Toy_private_emitAstError(bucketHandle, rootHandle);
return;
}
//build the name string
Toy_Token nameToken = parser->previous;
Toy_String* nameStr = Toy_createNameStringLength(bucketHandle, nameToken.lexeme, nameToken.length, TOY_VALUE_FUNCTION, true);
//read the function parameters, as a grouping
Toy_Ast* params = NULL;
parsePrecedence(bucketHandle, parser, &params, PREC_GROUP);
//read the body
Toy_Ast* body = NULL;
makeBlockStmt(bucketHandle, parser, &body);
//finally, emit the declaration as an Ast
Toy_private_emitAstFunctionDeclaration(bucketHandle, rootHandle, nameStr, params, body);
}
static void makeStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) { static void makeStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** rootHandle) {
//inner scope //inner scope
if (match(parser, TOY_TOKEN_OPERATOR_BRACE_LEFT)) { if (match(parser, TOY_TOKEN_OPERATOR_BRACE_LEFT)) {
@@ -984,10 +1009,10 @@ static void makeDeclarationStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, T
makeVariableDeclarationStmt(bucketHandle, parser, rootHandle); makeVariableDeclarationStmt(bucketHandle, parser, rootHandle);
} }
// //function declarations //function declarations
// else if (match(parser, TOY_TOKEN_KEYWORD_FUNCTION)) { else if (match(parser, TOY_TOKEN_KEYWORD_FUNCTION)) {
// makeFunctionDeclarationStmt(bucketHandle, parser, rootHandle); makeFunctionDeclarationStmt(bucketHandle, parser, rootHandle);
// } }
//otherwise //otherwise
else { else {

View File

@@ -50,6 +50,7 @@ int test_sizeof_ast(void) {
TEST_SIZEOF(Toy_AstVarDeclare, 12 , 24); TEST_SIZEOF(Toy_AstVarDeclare, 12 , 24);
TEST_SIZEOF(Toy_AstVarAssign, 16 , 24); TEST_SIZEOF(Toy_AstVarAssign, 16 , 24);
TEST_SIZEOF(Toy_AstVarAccess, 8 , 16); TEST_SIZEOF(Toy_AstVarAccess, 8 , 16);
TEST_SIZEOF(Toy_AstFnDeclare, 16 , 32);
TEST_SIZEOF(Toy_AstPass, 4 , 4); TEST_SIZEOF(Toy_AstPass, 4 , 4);
TEST_SIZEOF(Toy_AstError, 4 , 4); TEST_SIZEOF(Toy_AstError, 4 , 4);
TEST_SIZEOF(Toy_AstEnd, 4 , 4); TEST_SIZEOF(Toy_AstEnd, 4 , 4);