add declaration with function support

This commit is contained in:
2025-06-04 23:12:03 +01:00
parent 2bd0384060
commit 7b76b0d888
10 changed files with 125 additions and 17 deletions

View File

@@ -16,6 +16,7 @@ int yywrap(void * unused_param) {
%% %%
"." { return TOKEN_DOT; } "." { return TOKEN_DOT; }
"!" { return TOKEN_EXCLAMATION; }
"," { return TOKEN_COMMA; } "," { return TOKEN_COMMA; }
":" { return TOKEN_COLON; } ":" { return TOKEN_COLON; }

View File

@@ -71,6 +71,7 @@ typedef enum {
TOKEN_DOT, TOKEN_DOT,
TOKEN_COMMA, TOKEN_COMMA,
TOKEN_COLON, TOKEN_COLON,
TOKEN_EXCLAMATION,
} TokenType; } TokenType;
typedef struct { typedef struct {

View File

@@ -34,9 +34,11 @@ ParsedValue *parse_call(char *file, DArray *tokens, size_t *index,
break; break;
ParsedValue *parsedValue = parse_token(file, tokens, index, true); ParsedValue *parsedValue = parse_token(file, tokens, index, true);
darray_push(arg, parsedValue); darray_push(arg, parsedValue);
free(parsedValue);
switch (token->type) { switch (token->type) {
case TOKEN_COMMA: case TOKEN_COMMA:
darray_push(args, arg); darray_push(args, arg);
free(arg);
arg = checked_malloc(sizeof(DArray)); arg = checked_malloc(sizeof(DArray));
darray_init(arg, sizeof(ParsedValue)); darray_init(arg, sizeof(ParsedValue));
break; break;

View File

@@ -2,11 +2,12 @@
#include "../../lexer/token.h" #include "../../lexer/token.h"
#include "../../memory.h" #include "../../memory.h"
#include "../parser.h" #include "../parser.h"
#include "../literals/literals.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
ParsedValue *parse_declaration(char *file, DArray *parsed, DArray *tokens, ParsedValue *parse_declaration(char *file, DArray *tokens,
size_t *index) { size_t *index) {
(*index)++; (*index)++;
error_if_finished(file, tokens, index); error_if_finished(file, tokens, index);
@@ -14,6 +15,8 @@ ParsedValue *parse_declaration(char *file, DArray *parsed, DArray *tokens,
ParsedValue * parsedValue = malloc(sizeof(ParsedValue)); ParsedValue * parsedValue = malloc(sizeof(ParsedValue));
ParsedDeclaration * declaration = malloc(sizeof(ParsedDeclaration)); ParsedDeclaration * declaration = malloc(sizeof(ParsedDeclaration));
declaration->is_function = false;
declaration->from = parse_null();
parsedValue->data = declaration; parsedValue->data = declaration;
parsedValue->type = AST_DECLARATION; parsedValue->type = AST_DECLARATION;
@@ -23,8 +26,51 @@ ParsedValue *parse_declaration(char *file, DArray *parsed, DArray *tokens,
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
declaration->name = strcpy(checked_malloc(sizeof(token->value)), token->value); declaration->name = strcpy(checked_malloc(sizeof(token->value)), token->value);
(*index)++; (*index)++;
if ((*index) >= tokens->size) return parsedValue; if ((*index) >= tokens->size) {
return parsedValue;
}
token = darray_get(tokens, *index); token = darray_get(tokens, *index);
if (token->type == TOKEN_LPAREN) {
declaration->is_function = true;
declaration->parameters = checked_malloc(sizeof(DArray));
darray_init(declaration->parameters, sizeof(char*));
(*index)++;
error_if_finished(file, tokens, index);
while(true) {
token = darray_get(tokens, *index);
if (token->type != TOKEN_IDENTIFIER) {
fprintf(stderr, "%s:%u:%u error: parameter names need to start with a letter or _, only use letters, digits, or _, and can't be keywords.\n",
file, token->line, token->column);
exit(EXIT_FAILURE);
}
darray_push(declaration->parameters, strcpy(checked_malloc(sizeof(token->value)), token->value));
(*index)++;
error_if_finished(file, tokens, index);
token = darray_get(tokens, *index);
if (token->type == TOKEN_RPAREN) {
(*index)++;
error_if_finished(file, tokens, index);
token = darray_get(tokens, *index);
break;
} else if (token->type != TOKEN_COMMA) {
fprintf(stderr, "%s:%u:%u error: expected comma\n",
file, token->line, token->column);
exit(EXIT_FAILURE);
}
(*index)++;
error_if_finished(file, tokens, index);
}
}
if (token->type != TOKEN_ASSIGN) return parsedValue;
(*index)++;
error_if_finished(file, tokens, index);
free(declaration->from);
declaration->from = parse_token(file, tokens, index, true);
return parsedValue; return parsedValue;
} }

View File

@@ -6,11 +6,12 @@
typedef struct { typedef struct {
char * name; char * name;
bool is_function; bool is_function;
DArray args; // string[] DArray * parameters; // string[]
ParsedValue * from; ParsedValue * from;
} ParsedDeclaration; } ParsedDeclaration;
// Function declaration for parsing an identifier // Function declaration for parsing an identifier
ParsedValue *parse_declaration(char *file, DArray *parsed, DArray *tokens, size_t *index); ParsedValue *parse_declaration(char *file, DArray *tokens,
size_t *index);
#endif // DECLARATION_H #endif // DECLARATION_H

View File

@@ -0,0 +1,29 @@
#include "literals.h"
#include "../parser.h"
#include <stdbool.h>
#include "../../memory.h"
static bool true_value = true;
static bool false_value = false;
ParsedValue * parse_true(){
ParsedValue * parsedValue = checked_malloc(sizeof(ParsedValue));
parsedValue->type = AST_BOOLEAN;
parsedValue->data = &true_value;
return parsedValue;
};
ParsedValue * parse_false(){
ParsedValue * parsedValue = checked_malloc(sizeof(ParsedValue));
parsedValue->type = AST_BOOLEAN;
parsedValue->data = &false_value;
return parsedValue;
};
ParsedValue * parse_null(){
ParsedValue * parsedValue = checked_malloc(sizeof(ParsedValue));
parsedValue->type = AST_NULL;
parsedValue->data = NULL;
return parsedValue;
};

View File

@@ -0,0 +1,10 @@
#ifndef LITERALS_H
#define LITERALS_H
#include "../parser.h"
ParsedValue * parse_true();
ParsedValue * parse_false();
ParsedValue * parse_null();
#endif // LITERALS_H

View File

@@ -3,9 +3,11 @@
#include "../lexer/token.h" #include "../lexer/token.h"
#include "assignable/assign/assign.h" #include "assignable/assign/assign.h"
#include "assignable/identifier/identifier.h" #include "assignable/identifier/identifier.h"
#include "declaration/declaration.h"
#include "if/if.h" #include "if/if.h"
#include "number/number.h" #include "number/number.h"
#include "string/string.h" #include "string/string.h"
#include "literals/literals.h"
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
@@ -14,7 +16,7 @@
const char *ValueTypeNames[] = {"string", "assign", "identifier", const char *ValueTypeNames[] = {"string", "assign", "identifier",
"number", "if statement", "access", "number", "if statement", "access",
"call"}; "call", "declaration", "null", "boolean"};
void error_if_finished(char *file, DArray *tokens, size_t *index) { void error_if_finished(char *file, DArray *tokens, size_t *index) {
if ((*index) >= tokens->size) { if ((*index) >= tokens->size) {
@@ -25,11 +27,11 @@ void error_if_finished(char *file, DArray *tokens, size_t *index) {
} }
} }
ParsedValue *parse_token(char *file, DArray *tokens, ParsedValue *parse_token(char *file, DArray *tokens, size_t *index,
size_t *index, bool inline_flag) { bool inline_flag) {
Token *token = darray_get(tokens, *index); Token *token = darray_get(tokens, *index);
ParsedValue * output = NULL; ParsedValue *output = NULL;
if (!inline_flag) { if (!inline_flag) {
switch (token->type) { switch (token->type) {
@@ -40,6 +42,18 @@ ParsedValue *parse_token(char *file, DArray *tokens,
}; };
} }
switch (token->type) { switch (token->type) {
case TOKEN_TRUE:
(*index)++;
output = parse_true();
break;
case TOKEN_FALSE:
(*index)++;
output = parse_false();
break;
case TOKEN_NULL:
(*index)++;
output = parse_null();
break;
case TOKEN_STRING: case TOKEN_STRING:
(*index)++; (*index)++;
output = parse_string(*token); output = parse_string(*token);
@@ -64,6 +78,9 @@ ParsedValue *parse_token(char *file, DArray *tokens,
(*index)++; (*index)++;
output = parse_number(token); output = parse_number(token);
break; break;
case TOKEN_LET:
output = parse_declaration(file, tokens, index);
break;
default: default:
fprintf(stderr, "%s:%u:%u error: syntax error\n", file, token->line, fprintf(stderr, "%s:%u:%u error: syntax error\n", file, token->line,
token->column); token->column);
@@ -96,8 +113,7 @@ ParsedValue *parse_token(char *file, DArray *tokens,
void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) { void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) {
size_t index = 0; size_t index = 0;
while (index < tokens->size) { while (index < tokens->size) {
ParsedValue *parsed_code = ParsedValue *parsed_code = parse_token(file, tokens, &index, inline_flag);
parse_token(file, tokens, &index, inline_flag);
if (parsed_code) { if (parsed_code) {
darray_push(parsed, parsed_code); darray_push(parsed, parsed_code);
free(parsed_code); free(parsed_code);
@@ -116,6 +132,8 @@ void free_parsed(void *ptr) {
free_parse_assign(parsed); free_parse_assign(parsed);
break; break;
case AST_NUMBER: case AST_NUMBER:
case AST_NULL:
case AST_BOOLEAN:
break; break;
case AST_IF: case AST_IF:
free_parsed_if(parsed); free_parsed_if(parsed);

View File

@@ -15,7 +15,9 @@ typedef enum {
AST_IF, AST_IF,
AST_ACCESS, AST_ACCESS,
AST_CALL, AST_CALL,
AST_DECLARATION AST_DECLARATION,
AST_NULL,
AST_BOOLEAN
} ValueType; } ValueType;
extern const char* ValueTypeNames[]; extern const char* ValueTypeNames[];

View File

@@ -1,4 +1,2 @@
let y = 0 let a
let x = 10 a = 10
if (y) x += 1