]> Nishi Git Mirror - serenade.git/commitdiff
parser kinda works
authornishi <nishi@0f02c867-ac3d-714e-8a88-971ba1f6efcf>
Tue, 23 Apr 2024 05:04:40 +0000 (05:04 +0000)
committernishi <nishi@0f02c867-ac3d-714e-8a88-971ba1f6efcf>
Tue, 23 Apr 2024 05:04:40 +0000 (05:04 +0000)
git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@11 0f02c867-ac3d-714e-8a88-971ba1f6efcf

Serenade/Makefile
Serenade/main.c
Serenade/parser.c
Serenade/parser.h
Serenade/util.c [new file with mode: 0644]
Serenade/util.h [new file with mode: 0644]
Tool/configgen.c

index a2412fc0fd45482633b1bd24eedef347cc5bb954..9a8de3814cdb74879adebffcc17e2bb19bdb9406 100644 (file)
@@ -1,6 +1,6 @@
 # $Id$
 
-SERENADE_OBJS = main.o parser.o
+SERENADE_OBJS = main.o parser.o util.o
 
 .PHONY: all clean
 .SUFFIXES: .o .c
index e79e2be8e7606ab401b68171417dea14b8076bac..ac211f1952fab6c7bd63f91002de0c8e0a2eeb04 100644 (file)
 /* --- END LICENSE --- */
 
 #include "serenade.h"
+#include "parser.h"
 #include "../config.h"
 
 #include <string.h>
 #include <stdbool.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
 
 int main(int argc, char** argv){
        int i;
@@ -43,6 +46,7 @@ int main(int argc, char** argv){
                        if(strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-V") == 0){
                                printf("Serenade LISP %s\n", SERENADE_VERSION);
                                printf("Support: %s\n", SUPPORT);
+                               printf("Stack size: %d\n", STACK_SIZE);
                                return 1;
                        }else{
                                fprintf(stderr, "%s: %s: invalid option\n", argv[0], argv[i]);
@@ -51,12 +55,36 @@ int main(int argc, char** argv){
                }else{
                        /* file input */
                        loaded = true;
+                       struct stat s;
+                       if(stat(argv[i], &s) == 0){
+                               char* str = malloc(s.st_size);
+                               FILE* f = fopen(argv[i], "rb");
+                               if(f == NULL){
+                                       fprintf(stderr, "%s: %s: fopen fail\n", argv[0], argv[i]);
+                                       free(str);
+                                       return 1;
+                               }
+                               fread(str, 1, s.st_size, f);
+                               struct sn_generic** t = sn_parse(str, s.st_size);
+                               if(t != NULL){
+                                       int j;
+                                       for(j = 0; t[j] != NULL; j++){
+                                               sn_generic_free(t[j]);
+                                       }
+                                       free(t);
+                               }
+                               free(str);
+                       }else{
+                               fprintf(stderr, "%s: %s: stat fail\n", argv[0], argv[i]);
+                               return 1;
+                       }
                }
        }
 #ifdef HAS_REPL_SUPPORT
        if(!loaded){
                printf("Welcome to Serenade LISP %s\n", SERENADE_VERSION);
                printf("Support: %s\n", SUPPORT);
+               printf("Stack size: %d\n", STACK_SIZE);
        }
        return 0;
 #else
index f96c9ec5569624d413ab03df9bc8efb18815ad6a..263b8a9cee78885a76382b023ba59fda76d8ac3a 100644 (file)
 /* --- END LICENSE --- */
 
 #include "parser.h"
+#include "util.h"
+#include "../config.h"
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+struct sn_generic {
+       int type;
+       double number;
+       char* string;
+       unsigned long long string_length;
+       void* ptr;
+       struct sn_tree* tree;
+};
+*/
+
+struct sn_generic* sn_expr_parse(char* data, unsigned long long size){
+       int i;
+       int br = 0;
+       bool dq = false;
+       int* br_stack = malloc(sizeof(*br_stack) * STACK_SIZE);
+       char** op_stack = malloc(sizeof(*op_stack) * STACK_SIZE);
+       struct sn_generic** gn_stack = malloc(sizeof(*gn_stack) * STACK_SIZE);
+       for(i = 0; i < STACK_SIZE; i++){
+               br_stack[i] = 0;
+               op_stack[i] = NULL;
+               gn_stack[i] = NULL;
+       }
+       for(i = 0; i < size; i++){
+               char c = data[i];
+               if(c == '"'){
+                       dq = !dq;
+               }else if(dq){
+               }else if(c == '('){
+                       br++;
+                       gn_stack[br - 1] = malloc(sizeof(*gn_stack));
+                       gn_stack[br - 1]->type = SN_TYPE_TREE;
+                       gn_stack[br - 1]->tree = malloc(sizeof(*gn_stack[br - 1]->tree));
+                       gn_stack[br - 1]->tree->op = malloc(sizeof(*gn_stack[br - 1]->tree->op));
+                       gn_stack[br - 1]->tree->op->type = SN_TYPE_FUNCTION;
+                       gn_stack[br - 1]->tree->args = malloc(sizeof(*gn_stack[br - 1]->tree->args));
+                       gn_stack[br - 1]->tree->args[0] = NULL;
+                       op_stack[br - 1] = malloc(1);
+                       op_stack[br - 1][0] = 0;
+               }else if(c == ')'){
+                       if(br == 1){
+                               gn_stack[br - 1]->tree->op->name = sn_strdup(op_stack[br - 1]);
+                       }
+                       br_stack[br - 1] = 0;
+                       if(br_stack[br - 2] > 0){
+                               int j;
+                               struct sn_generic** old_args = gn_stack[br - 2]->tree->args;
+                               for(j = 0; old_args[j] != NULL; j++);
+                               gn_stack[br - 2]->tree->args = malloc(sizeof(*gn_stack[br - 2]->tree->args) * (j + 2));
+                               for(j = 0; old_args[j] != NULL; j++){
+                                       gn_stack[br - 2]->tree->args[j] = old_args[j];
+                               }
+                               gn_stack[br - 2]->tree->args[j] = gn_stack[br - 1];
+                               gn_stack[br - 2]->tree->args[j + 1] = NULL;
+                               free(old_args);
+                       }
+                       br--;
+               }else if(br > 0){
+                       if(c == ' '){
+                               br_stack[br - 1]++;
+                       }else if(br_stack[br - 1] == 0){
+                               char cbuf[2];
+                               cbuf[0] = c;
+                               cbuf[1] = 0;
+                               char* tmp = op_stack[br - 1];
+                               op_stack[br - 1] = sn_strcat(tmp, cbuf);
+                               free(tmp);
+                       }
+               }
+       }
+       struct sn_generic* gen = gn_stack[0];
+       free(gn_stack);
+       free(br_stack);
+       free(op_stack);
+       return gen;
+}
+
+struct sn_generic** sn_parse(char* data, unsigned long long size){
+       int br = 0;
+       int i;
+       int start = 0;
+       bool dq = false;
+       for(i = 0; i < size; i++){
+               char c = data[i];
+               if(c == '"'){
+                       dq = !dq;
+               }else if(dq){
+               }else if(c == '('){
+                       if(br == 0){
+                               start = i;
+                       }
+                       br++;
+               }else if(c == ')'){
+                       br--;
+                       if(br == 0){
+                               char* d = malloc(i - start + 1);
+                               memcpy(d, data + start, i - start + 1);
+                               struct sn_generic* gen = sn_expr_parse(d, i - start + 1);
+                               if(gen != NULL){
+                                       sn_generic_free(gen);
+                               }
+                               free(d);
+                       }
+               }
+       }
+       return NULL;
+}
+
+void sn_generic_free(struct sn_generic* g){
+       if(g->type == SN_TYPE_STRING){
+               free(g->string);
+       }else if(g->type == SN_TYPE_TREE){
+               sn_tree_free(g->tree);
+       }
+       free(g);
+}
+
+void sn_tree_free(struct sn_tree* t){
+       if(t->op != NULL){
+               sn_generic_free(t->op);
+       }
+       if(t->args != NULL){
+               int i;
+               for(i = 0; t->args[i] != NULL; i++){
+                       sn_generic_free(t->args[i]);
+               }
+               free(t->args);
+       }
+}
index eb14ffb23aed0e456f80259f4e153e176a4fd508..08b21f1a09e79531f84b19af42745612ec088184 100644 (file)
@@ -35,6 +35,8 @@ enum types {
        SN_TYPE_DOUBLE,
        SN_TYPE_STRING,
        SN_TYPE_TREE,
+       SN_TYPE_PTR,
+       SN_TYPE_FUNCTION,
        SN_TYPE_VOID
 };
 
@@ -42,12 +44,19 @@ struct sn_generic {
        int type;
        double number;
        char* string;
+       unsigned long long string_length;
+       void* ptr;
+       char* name;
        struct sn_tree* tree;
 };
 
 struct sn_tree {
-       struct sn_generic* type;
+       struct sn_generic* op;
        struct sn_generic** args;
 };
 
+struct sn_generic** sn_parse(char* data, unsigned long long size);
+void sn_generic_free(struct sn_generic* g);
+void sn_tree_free(struct sn_tree* t);
+
 #endif
diff --git a/Serenade/util.c b/Serenade/util.c
new file mode 100644 (file)
index 0000000..cb87438
--- /dev/null
@@ -0,0 +1,23 @@
+/* $Id$ */
+/* --- START LICENSE --- */
+/* --- END LICENSE --- */
+
+#include "util.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+char* sn_strcat(const char* str1, const char* str2){
+       char* str = malloc(strlen(str1) + strlen(str2) + 1);
+       memcpy(str, str1, strlen(str1));
+       memcpy(str + strlen(str1), str2, strlen(str2));
+       str[strlen(str1) + strlen(str2)] = 0;
+       return str;
+}
+
+char* sn_strdup(const char* str1){
+       char* str = malloc(strlen(str1) + 1);
+       memcpy(str, str1, strlen(str1));
+       str[strlen(str1)] = 0;
+       return str;
+}
diff --git a/Serenade/util.h b/Serenade/util.h
new file mode 100644 (file)
index 0000000..c27e43c
--- /dev/null
@@ -0,0 +1,11 @@
+/* $Id$ */
+/* --- START LICENSE --- */
+/* --- END LICENSE --- */
+
+#ifndef __SERENADE_UTIL_H__
+#define __SERENADE_UTIL_H__
+
+char* sn_strcat(const char* str1, const char* str2);
+char* sn_strdup(const char* str1);
+
+#endif
index 2a6f6c69584f60246075945a741b48e176b3b5d8..87082c4b685ab81ff01e714405f02c51472e1c21 100644 (file)
@@ -89,6 +89,11 @@ int main(int argc, char** argv){
                        nl = true;
                }
        }
+       int stack_size = 1024;
+       fprintf(stderr, "[recommended: 1024] Stack size? ");
+       fflush(stderr);
+       scanf("%d", &stack_size);
+       fprintf(out, "#define STACK_SIZE %d\n", stack_size);
        fprintf(out, "#define SUPPORT \"");
        for(n = 0; asks[n * 4] != NULL; n++){
                if(n > 0) fprintf(out, " ");