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_EXCLAMATION; }
"," { return TOKEN_COMMA; }
":" { return TOKEN_COLON; }

View File

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

View File

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

View File

@@ -2,11 +2,12 @@
#include "../../lexer/token.h"
#include "../../memory.h"
#include "../parser.h"
#include "../literals/literals.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
ParsedValue *parse_declaration(char *file, DArray *parsed, DArray *tokens,
ParsedValue *parse_declaration(char *file, DArray *tokens,
size_t *index) {
(*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));
ParsedDeclaration * declaration = malloc(sizeof(ParsedDeclaration));
declaration->is_function = false;
declaration->from = parse_null();
parsedValue->data = declaration;
parsedValue->type = AST_DECLARATION;
@@ -23,8 +26,51 @@ ParsedValue *parse_declaration(char *file, DArray *parsed, DArray *tokens,
exit(EXIT_FAILURE);
}
declaration->name = strcpy(checked_malloc(sizeof(token->value)), token->value);
(*index)++;
if ((*index) >= tokens->size) return parsedValue;
if ((*index) >= tokens->size) {
return parsedValue;
}
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;
}

View File

@@ -6,11 +6,12 @@
typedef struct {
char * name;
bool is_function;
DArray args; // string[]
DArray * parameters; // string[]
ParsedValue * from;
} ParsedDeclaration;
// 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

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

View File

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

View File

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