From 035cd53983a49af8210dd3bc6e94ad847ca83801 Mon Sep 17 00:00:00 2001 From: ghostie Date: Sat, 5 Jul 2025 12:36:26 -0500 Subject: [PATCH] defining some structs for the ast --- Makefile | 12 ++++++-- src/lexer.c | 20 +++++++++++-- src/lexer.h | 1 + src/main.c | 17 ++++------- src/model.c | 36 ++++++++++++++++++++++ src/model.h | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ src/parser.c | 22 ++++++++++++++ src/parser.h | 16 ++++++++++ src/token.h | 3 +- tests/expr.pinky | 4 ++- 10 files changed, 191 insertions(+), 18 deletions(-) create mode 100644 src/model.c create mode 100644 src/model.h create mode 100644 src/parser.c create mode 100644 src/parser.h diff --git a/Makefile b/Makefile index 92b7bfa..ad27600 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ RM=rm CFLAGS=-Wall -Werror -std=gnu99 -O0 -g LIBS= -FILES=build/main.o build/lexer.o build/token.o build/utils/vector.o build/utils/buffer.o +FILES=build/main.o build/lexer.o build/token.o build/parser.o build/model.o build/utils/vector.o build/utils/buffer.o OUT=bin/pinky.out all: $(FILES) @@ -24,6 +24,14 @@ build/token.o: src/token.c @$(ECHO) "CC\t\t"$< @$(CC) $(CFLAGS) $< -c -o $@ $(LIBS) +build/parser.o: src/parser.c + @$(ECHO) "CC\t\t"$< + @$(CC) $(CFLAGS) $< -c -o $@ $(LIBS) + +build/model.o: src/model.c + @$(ECHO) "CC\t\t"$< + @$(CC) $(CFLAGS) $< -c -o $@ $(LIBS) + build/utils/vector.o: src/utils/vector.c @$(ECHO) "CC\t\t"$< @$(CC) $(CFLAGS) $< -c -o $@ $(LIBS) @@ -33,7 +41,7 @@ build/utils/buffer.o: src/utils/buffer.c @$(CC) $(CFLAGS) $< -c -o $@ $(LIBS) run: all - @$(OUT) tests/program.pinky + @$(OUT) tests/expr.pinky clean: @$(ECHO) "Cleaning..." diff --git a/src/lexer.c b/src/lexer.c index e1b284d..168e6ca 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -275,8 +275,16 @@ lexer_lex (struct lexer *l) else if (c == '%') add_token (TOK_MOD, l); /* multi-character tokens */ - else if (c == '=' && match ('=', l)) - add_token (TOK_EQ, l); + else if (c == '=') + { + if (match ('=', l)) + { + add_token (TOK_EQEQ, l); + continue; + } + + add_token (TOK_EQ, l); + } else if (c == '~') add_token (match ('=', l) ? TOK_EQ : TOK_NOT, l); else if (c == '<') @@ -297,6 +305,14 @@ lexer_lex (struct lexer *l) } } +struct vector * +lexer_get_tokens (struct lexer *l) +{ + if (!l) + return NULL; + return &l->tokens; +} + void lexer_print (struct lexer *l) { diff --git a/src/lexer.h b/src/lexer.h index edef1a9..fba4a27 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -15,6 +15,7 @@ struct lexer struct lexer lexer_create (); void lexer_set_source (struct buffer *b, struct lexer *l); void lexer_lex (struct lexer *l); +struct vector *lexer_get_tokens (struct lexer *l); void lexer_print (struct lexer *l); void lexer_free (struct lexer *lexer); diff --git a/src/main.c b/src/main.c index 03fbf9b..46541fd 100644 --- a/src/main.c +++ b/src/main.c @@ -1,11 +1,10 @@ #include #include -#include - #include "utils/buffer.h" #include "lexer.h" +#include "parser.h" int main (int argc, char **argv) @@ -16,9 +15,6 @@ main (int argc, char **argv) return EXIT_FAILURE; } - struct timespec ts1, ts2; - clock_gettime (CLOCK_REALTIME, &ts1); - struct buffer code = buffer_create (); if (!buffer_read (argv[1], &code)) return EXIT_FAILURE; @@ -28,15 +24,12 @@ main (int argc, char **argv) lexer_lex (&lexer); lexer_print (&lexer); + struct parser parser = parser_create (lexer_get_tokens (&lexer)); + parser_parse (&parser); + parser_print (&parser); + lexer_free (&lexer); buffer_free (&code); - clock_gettime (CLOCK_REALTIME, &ts2); - unsigned long long ndiff = ts2.tv_nsec - ts1.tv_nsec; - unsigned long long sdiff = ts2.tv_sec - ts1.tv_sec; - - printf ("it took %llu nanoseconds and %llu seconds to complete.\n", ndiff, - sdiff); - return EXIT_SUCCESS; } diff --git a/src/model.c b/src/model.c new file mode 100644 index 0000000..013222d --- /dev/null +++ b/src/model.c @@ -0,0 +1,36 @@ +#include "model.h" + +struct expression +expression_create_integer (int value) +{ + return (struct expression){ .type = EXPR_INT, .integer = value }; +} + +struct expression +expression_create_floating (int value) +{ + return (struct expression){ .type = EXPR_FLOAT, .floating = value }; +} + +struct expression +expression_create_binop (struct token *op, struct expression *left, + struct expression *right) +{ + return (struct expression){ .type = EXPR_BINOP, + .binop + = { .op = op, .left = left, .right = right } }; +} + +struct expression +expression_create_unop (struct token *op, struct expression *operand) +{ + return (struct expression){ .type = EXPR_UNOP, + .unop = { .op = op, .operand = operand } }; +} + +struct expression +expression_create_grouping (struct expression *value) +{ + return (struct expression){ .type = EXPR_GROUP, + .grouping = { .value = value } }; +} diff --git a/src/model.h b/src/model.h new file mode 100644 index 0000000..633a08c --- /dev/null +++ b/src/model.h @@ -0,0 +1,78 @@ +#ifndef __MODEL_H +#define __MODEL_H + +#include "token.h" + +/******************************** + * Expression + ********************************/ +enum expression_type +{ + EXPR_INT, + EXPR_FLOAT, + EXPR_BINOP, + EXPR_UNOP, + EXPR_GROUP +}; + +struct expression +{ + enum expression_type type; + + union + { + /* integer (i.e. 2) */ + int integer; + + /* floating (i.e. 3.141592) */ + float floating; + + struct + { + /* binary operations (i.e. x + y) */ + struct token *op; + struct expression *left; + struct expression *right; + } binop; + + struct + { + /* unary operations (i.e. -x) */ + struct token *op; + struct expression *operand; + } unop; + + struct + { + /* grouping: ( ) */ + struct expression *value; + } grouping; + }; +}; +struct expression expression_create_integer (int value); +struct expression expression_create_floating (int value); +struct expression expression_create_binop (struct token *op, + struct expression *left, + struct expression *right); +struct expression expression_create_unop (struct token *op, + struct expression *operand); +struct expression expression_create_grouping (struct expression *value); + +/******************************** + * Statements + ********************************/ +struct stmt +{ + union + { + struct + { + } while_stmt; + + struct + { + } assignment; + }; +}; + +#endif diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..286d1aa --- /dev/null +++ b/src/parser.c @@ -0,0 +1,22 @@ +#include "parser.h" + +#include + +struct parser +parser_create (struct vector *tokens) +{ + return (struct parser){ .tokens = tokens, .curr = 0 }; +} + +void +parser_parse (struct parser *p) +{ + if (!p) + return; +} + +void +parser_print (struct parser *p) +{ + puts ("Parser:"); +} diff --git a/src/parser.h b/src/parser.h new file mode 100644 index 0000000..7926278 --- /dev/null +++ b/src/parser.h @@ -0,0 +1,16 @@ +#ifndef __PARSER_H +#define __PARSER_H + +#include "utils/vector.h" + +struct parser +{ + struct vector *tokens; + unsigned int curr; +}; + +struct parser parser_create (struct vector *tokens); +void parser_parse (struct parser *p); +void parser_print (struct parser *p); + +#endif diff --git a/src/token.h b/src/token.h index cfb513a..0faf4bc 100644 --- a/src/token.h +++ b/src/token.h @@ -26,12 +26,13 @@ enum token_type TOK_NOT, TOK_GT, TOK_LT, + TOK_EQ, /* multiple character tokens */ TOK_GE, TOK_LE, TOK_NE, - TOK_EQ, + TOK_EQEQ, TOK_ASSIGN, TOK_GTGT, TOK_LTLT, diff --git a/tests/expr.pinky b/tests/expr.pinky index 63ec10c..af8e105 100644 --- a/tests/expr.pinky +++ b/tests/expr.pinky @@ -1,2 +1,4 @@ +-------------------------------- -- Evaluate a simple expression -2 + 3 \ No newline at end of file +-------------------------------- +2 + 42 * 2 + (47 * -21) \ No newline at end of file