7 Ревизии a5d76dd982 ... 69bb58c9ce

Автор SHA1 Съобщение Дата
  Steven 69bb58c9ce makefile more explicit and changed syntax back преди 9 години
  Steven 81e56209c0 underscore support преди 9 години
  Steven c6d0d5e1d5 syntax change (function call and function prototype) and better colors преди 9 години
  soud f60b017e17 formatting преди 9 години
  soud bde246e062 some docs added, import keyword change преди 9 години
  soud c3030c25b0 ast destroyer improved преди 9 години
  soud 1bd85b9ed4 moved ast related stuff to ast files преди 9 години
променени са 10 файла, в които са добавени 142 реда и са изтрити 78 реда
  1. 5 6
      Makefile
  2. 3 3
      examples/fibonacci.er
  3. 7 5
      examples/parse.er
  4. 78 37
      src/ast.c
  5. 7 1
      src/ast.h
  6. 10 6
      src/erupt.c
  7. 11 6
      src/erupt.h
  8. 19 12
      src/lexer.c
  9. 2 2
      src/lexer.h
  10. 0 0
      src/main.c

+ 5 - 6
Makefile

@@ -1,14 +1,13 @@
-CFLAGS=-Wall -Wextra -g -std=c11 `llvm-config --cflags` -c
+CFLAGS=-Wall -Wextra -O2 -std=c11 `llvm-config --cflags` -c
 LDFLAGS=`llvm-config --cxxflags --ldflags`
-CFILES=$(wildcard src/*.c)
-
-.PHONY: all clean
+CFILES=src/ast.c src/erupt.c src/lexer.c src/main.c src/parser.c src/token.c
+OBJFILES=ast.o erupt.o lexer.o main.o parser.o token.o
 
 all:
 	@mkdir -p bin/
 	$(CC) $(CFLAGS) $(CFILES)
-	$(CXX) *.o $(LDFLAGS) -o bin/erupt
-	@-rm *.o
+	$(CXX) $(OBJFILES) $(LDFLAGS) -o bin/erupt
+	@-rm -r $(OBJFILES)
 
 clean:
 	@rm *.o

+ 3 - 3
examples/fibonacci.er

@@ -1,4 +1,4 @@
-fn fibo(i64 n) : i64
+fun fibo(i64 n) -> i64
 {
     if n < 3 {
         return 1;
@@ -7,7 +7,7 @@ fn fibo(i64 n) : i64
     return fib(n - 2) + fib(n - 1);
 }
 
-fn main()
+fun main
 {
-    write(fibo(20));
+    write("Fibonacci sequence 20th number: ", fibo(20));
 }

+ 7 - 5
examples/parse.er

@@ -15,22 +15,24 @@
  *
  */
 
+use whatever_really;
+
 mut i32 glob_var = 5;
 
-fn main()
+fun main
 {
     mut i32 i = 0;
 
     while i < 20 {
-        if odd(i) {
+        if odd : i {
             i += 1;
         } else {
             i += 2;
-            write("else stmt");
+            write : "else stmt";
         }
 
-        write("in while");
+        write : "in while";
     }
 
-    write(i);
+    write : i;
 }

+ 78 - 37
src/ast.c

@@ -152,56 +152,97 @@ ast_node_t *create_bin_exp(ast_op_t operator, ast_node_t *lhs, ast_node_t *rhs)
         return node;
 }
 
-void destroy_ast(ast_node_t *node)
+void destroy_ast(ast_node_list_t *nl)
 {
-        switch(node->type) {
+        do {
+                switch(nl->node->type) {
+                case TYPE_VAR:
+                        if (nl->node->var.name)
+                                free(nl->node->var.name);
+                        break;
+                case TYPE_PROTO:
+                        if (nl->node->prototype.name)
+                                free(nl->node->prototype.name);
+
+                        for (size_t i = 0; i < nl->node->prototype.arg_count; ++i)
+                                free(nl->node->prototype.args[i]);
+
+                        free(nl->node->prototype.args);
+                        break;
+                case TYPE_FN:
+                        if (nl->node->fn.prototype)
+                                free(nl->node->fn.prototype);
+
+                        if (nl->node->fn.body)
+                                free(nl->node->fn.body);
+                        break;
+                case TYPE_CALL:
+                        if (nl->node->call.name)
+                                free(nl->node->call.name);
+
+                        for (size_t i = 0; i < nl->node->call.arg_count; ++i)
+                                free(nl->node->call.args[i]);
+
+                        free(nl->node->call.args);
+                        break;
+                case TYPE_IF:
+                        if (nl->node->if_exp.condition)
+                                free(nl->node->if_exp.condition);
+
+                        if (nl->node->if_exp.true_body)
+                                free(nl->node->if_exp.true_body);
+
+                        if (nl->node->if_exp.false_body)
+                                free(nl->node->if_exp.false_body);
+                        break;
+                case TYPE_BIN_EXP:
+                        if (nl->node->bin_exp.lhs)
+                                free(nl->node->bin_exp.lhs);
+                        if (nl->node->bin_exp.rhs)
+                                free(nl->node->bin_exp.rhs);
+                        break;
+                }
+
+                free(nl->node);
+                nl = nl->next;
+        } while (nl->next != NULL);
+
+        free(nl);
+        verbose_printf("destroyed ast\n");
+}
+
+
+static void dump_node(ast_node_t *node)
+{
+        switch (node->type) {
         case TYPE_VAR:
-                if (node->var.name)
-                        free(node->var.name);
+                printf("variable:\n\tname: %s\n\ttype: %u\n\tmutable:%d\n",
+                       node->var.name, node->var.data_type, node->var.mutable);
                 break;
         case TYPE_PROTO:
-                if (node->prototype.name)
-                        free(node->prototype.name);
-
-                for (size_t i = 0; i < node->prototype.arg_count; ++i)
-                        free(node->prototype.args[i]);
-
-                free(node->prototype.args);
+                printf("proto:\n\tname: %s\n\ttype: %u\n",
+                       node->prototype.name, node->prototype.data_type);
                 break;
         case TYPE_FN:
-                if (node->fn.prototype)
-                        free(node->fn.prototype);
-
-                if (node->fn.body)
-                        free(node->fn.body);
+                printf("function:\n");
+                dump_node(node->fn.prototype);
                 break;
         case TYPE_CALL:
-                if (node->call.name)
-                        free(node->call.name);
-
-                for (size_t i = 0; i < node->call.arg_count; ++i)
-                        free(node->call.args[i]);
-
-                free(node->call.args);
+                /* TODO */
                 break;
         case TYPE_IF:
-                if (node->if_exp.condition)
-                        free(node->if_exp.condition);
-
-                if (node->if_exp.true_body)
-                        free(node->if_exp.true_body);
-
-                if (node->if_exp.false_body)
-                        free(node->if_exp.false_body);
+                /* TODO */
                 break;
         case TYPE_BIN_EXP:
-                if (node->bin_exp.lhs)
-                        free(node->bin_exp.lhs);
-                if (node->bin_exp.rhs)
-                        free(node->bin_exp.rhs);
+                /* TODO */
                 break;
         }
+}
 
-        free(node);
-        verbose_printf("destroyed ast\n");
+void dump_nodes(ast_node_list_t *nl)
+{
+        do {
+                dump_node(nl->node);
+                nl = nl->next;
+        } while (nl->next != NULL);
 }

+ 7 - 1
src/ast.h

@@ -147,12 +147,18 @@ typedef struct ast_node {
         };
 } ast_node_t;
 
+typedef struct ast_node_list {
+        ast_node_t *node;
+        struct ast_node_list *next;
+} ast_node_list_t;
+
 ast_node_t *create_var(char *name, ast_type_t data_type, char *value, bool mutable);
 ast_node_t *create_fn_proto(char *name, ast_var_t **args, size_t arg_count, ast_type_t data_type);
 ast_node_t *create_fn(ast_node_t *prototype, ast_node_t *body);
 ast_node_t *create_call(char *name, ast_node_t **args, size_t arg_count);
 ast_node_t *create_if(ast_node_t *condition, ast_node_t *true_body, ast_node_t *false_body);
 ast_node_t *create_bin_exp(ast_op_t operator, ast_node_t *lhs, ast_node_t *rhs);
-void destroy_ast(ast_node_t *node);
+void destroy_ast(ast_node_list_t *nl);
+void dump_nodes(ast_node_list_t *nl);
 
 #endif /* !AST_H */

+ 10 - 6
src/erupt.c

@@ -23,8 +23,9 @@
 #include <stdarg.h>
 #include "erupt.h"
 
-bool VERBOSE = 0;
-bool SHOW_TOKENS = 0;
+bool VERBOSE = false;
+bool SHOW_TOKENS = false;
+bool SHOW_NODES = false;
 char *TARGET_FILE = "unknown";
 char *OUTPUT_NAME = "main";
 
@@ -62,7 +63,7 @@ void verbose_printf(const char *fmt, ...)
         va_list arg;
         va_start(arg, fmt);
 
-        printf("[*] ");
+        printf(BOLD "[*] " COLOR_RESET);
         vprintf(fmt, arg);
 
         va_end(arg);
@@ -74,7 +75,8 @@ void warning_printf(const char *m, const char *fmt, ...)
 
         va_start(arg, fmt);
 
-        fprintf(stderr, "%s: %s: ", m, ORANGE("warning"));
+        fprintf(stderr, BOLD "[%s]" COLOR_RESET " %s: ",
+                        m, (BOLD YELLOW_TEXT "warning" COLOR_RESET));
         vfprintf(stderr, fmt, arg);
 
         va_end(arg);
@@ -86,7 +88,8 @@ void error_printf(const char *m, const char *fmt, ...)
 
         va_start(arg, fmt);
 
-        fprintf(stderr, "%s: %s: ", m, RED("error"));
+        fprintf(stderr, BOLD "[%s]" COLOR_RESET " %s: ",
+                        m, (BOLD RED_TEXT "error" COLOR_RESET));
         vfprintf(stderr, fmt, arg);
 
         va_end(arg);
@@ -99,7 +102,8 @@ void fatal_error(const char *m, const char *fmt, ...)
 
         va_start(arg, fmt);
 
-        fprintf(stderr, "%s: %s: ", m, RED("fatal error"));
+        fprintf(stderr, BOLD "[%s]" COLOR_RESET " %s: ",
+                        m, (BOLD RED_TEXT "fatal error" COLOR_RESET));
         vfprintf(stderr, fmt, arg);
 
         va_end(arg);

+ 11 - 6
src/erupt.h

@@ -47,17 +47,22 @@
 
 /* no colors for windows */
 #ifdef _WIN32
-        #define BOLD(x)   (x)
-        #define RED(x)    (x)
-        #define ORANGE(x) (x)
+        #define COLOR_RESET
+        #define BOLD
+        #define RED_TEXT
+        #define GREEN_TEXT
+        #define YELLOW_TEXT
 #else
-        #define BOLD(x)   ("\033[1m" x "\033[0m")
-        #define RED(x)    ("\x1B[31m" x "\x1B[00m")
-        #define ORANGE(x) ("\x1B[33m" x "\x1B[00m")
+        #define COLOR_RESET  "\033[0m"
+        #define BOLD         "\033[1m"
+        #define RED_TEXT     "\033[31;1m"
+        #define GREEN_TEXT   "\033[32;1m"
+        #define YELLOW_TEXT  "\033[33;1m"
 #endif
 
 extern bool VERBOSE;
 extern bool SHOW_TOKENS;
+extern bool SHOW_NODES;
 extern char *OUTPUT_NAME;
 extern char *TARGET_FILE;
 

+ 19 - 12
src/lexer.c

@@ -36,6 +36,7 @@ static void read_ident(lexer_t *lexer);
 static void read_comment(lexer_t *lexer);
 static void read_long_comment(lexer_t *lexer);
 
+/* string => ketword_t "map" for detecting keywords */
 static keyword_t keywords[] = {
         {FUNCTION_KEYWORD , TOKEN_FUNCTION},
         {TRUE_KEYWORD     , TOKEN_TRUE},
@@ -77,6 +78,13 @@ lexer_t *tokenize(char *target_file, char *source)
                 case '"': read_string(lexer, '"'); break;
                 case '\'': read_string(lexer, '\''); break;
                 case '\n': ++lexer->line_n; break;
+                case '_':
+                        if (is_ident(peek(lexer))) {
+                                read_ident(lexer);
+                        } else {
+                                emit_token(lexer, TOKEN_UNDERSCORE);
+                        }
+                        break;
                 case '+':
                         if (peek(lexer) == '=') {
                                 eat(lexer);
@@ -89,6 +97,9 @@ lexer_t *tokenize(char *target_file, char *source)
                         if (peek(lexer) == '=') {
                                 eat(lexer);
                                 emit_token(lexer, TOKEN_MIN_EQ);
+                        } else if (peek(lexer) == '>'){
+                                eat(lexer);
+                                emit_token(lexer, TOKEN_R_ARROW);
                         } else {
                                 emit_token(lexer, TOKEN_MIN);
                         }
@@ -105,26 +116,22 @@ lexer_t *tokenize(char *target_file, char *source)
                         if (peek(lexer) == '&') {
                                 eat(lexer);
                                 emit_token(lexer, TOKEN_AND);
+                        } else if (peek(lexer) == '=') {
+                                eat(lexer);
+                                emit_token(lexer, TOKEN_B_AND_EQ);
                         } else {
-                                if (peek(lexer) == '=') {
-                                        eat(lexer);
-                                        emit_token(lexer, TOKEN_B_AND_EQ);
-                                } else {
-                                        emit_token(lexer, TOKEN_B_AND);
-                                }
+                                emit_token(lexer, TOKEN_B_AND);
                         }
                         break;
                 case '|':
                         if (peek(lexer) == '|') {
                                 eat(lexer);
                                 emit_token(lexer, TOKEN_OR);
+                        } else if (peek(lexer) == '=') {
+                                eat(lexer);
+                                emit_token(lexer, TOKEN_B_OR_EQ);
                         } else {
-                                if (peek(lexer) == '=') {
-                                        eat(lexer);
-                                        emit_token(lexer, TOKEN_B_OR_EQ);
-                                } else {
-                                        emit_token(lexer, TOKEN_B_OR);
-                                }
+                                emit_token(lexer, TOKEN_B_OR);
                         }
                         break;
                 case '~':

+ 2 - 2
src/lexer.h

@@ -25,11 +25,11 @@
 
 #include "token.h"
 
-#define FUNCTION_KEYWORD "fn"
+#define FUNCTION_KEYWORD "fun"
 #define TRUE_KEYWORD     "true"
 #define FALSE_KEYWORD    "false"
 #define MUTABLE_KEYWORD  "mut"
-#define IMPORT_KEYWORD   "using"
+#define IMPORT_KEYWORD   "use"
 #define RETURN_KEYWORD   "return"
 #define FOR_KEYWORD      "for"
 #define WHILE_KEYWORD    "while"

+ 0 - 0
src/main.c


Някои файлове не бяха показани, защото твърде много файлове са промени