]> git.mdlowis.com Git - proto/sclpl.git/commitdiff
Reworked parser and translation layer
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 19 Aug 2014 20:34:13 +0000 (16:34 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 19 Aug 2014 20:34:13 +0000 (16:34 -0400)
Gemfile.lock
Rakefile
source/sclpl/ast.h
source/sclpl/grammar.c
source/sclpl/grammar.y
source/sclpl/main.c

index b932f82cc9255c2c9428b8ad0f3e4923bd9078fe..7b3953a9124ab51dab310b7579010e1a33cdece2 100644 (file)
@@ -8,6 +8,7 @@ GEM
 
 PLATFORMS
   ruby
+  x86-mingw32
 
 DEPENDENCIES
   rake
index 8175ae221a9faf226805e1eaa901c3548c02af0d..894833db47e599f2f9e4576a271bba365c5ea003 100644 (file)
--- a/Rakefile
+++ b/Rakefile
@@ -8,6 +8,11 @@ rescue Bundler::BundlerError => e
   raise LoadError.new("Unable to Bundler.setup(): You probably need to run `bundle install`: #{e.message}")
 end
 require 'rscons'
+require 'rbconfig'
+
+def windows?
+  RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
+end
 
 #------------------------------------------------------------------------------
 # Clang Toolchain Targets
@@ -18,7 +23,7 @@ CLANG_BIN_NAME = 'clang'
 CLANG_SRC_DIR = 'source/vendor/llvm-3.4.2'
 CLANG_CMAKE_GENERATOR = ENV['CMAKE_GENERATOR'] || "Unix Makefiles"
 CLANG_CMAKE_OPTS = [ '-DCMAKE_BUILD_TYPE=Release' ]
-CLANG_MAKE_CMD = 'make'
+CLANG_MAKE_CMD = windows? ? 'nmake' : 'make'
 
 file "#{CLANG_BUILD_DIR}/Makefile" => FileList["#{CLANG_SRC_DIR}/cmake/**/*"] do
     FileUtils.mkdir_p(CLANG_BUILD_DIR)
@@ -34,7 +39,7 @@ file "#{CLANG_BIN_DIR}/#{CLANG_BIN_NAME}" => ["#{CLANG_BUILD_DIR}/Makefile"] + F
 end
 
 task :clang => ["#{CLANG_BIN_DIR}/#{CLANG_BIN_NAME}"] do
-    ENV['PATH'].unshift(CLANG_BIN_DIR)
+    ENV['PATH'] = "#{CLANG_BIN_DIR}#{windows? ? ';':':'}#{ENV['PATH']}"
 end
 
 #------------------------------------------------------------------------------
@@ -70,7 +75,7 @@ end
 task :default => [:build]
 
 desc "Build all targets"
-task :build => [:sclpl]
+task :build => [:clang, :sclpl]
 
 desc "Build the sclpl compiler and interpreter"
 task :sclpl => ['source/sclpl/grammar.c'] do
index 0e124f7a8e969a1575153e05087a9e7809bd81ce..12f11c6780217abe39804849860def83f15fdb70 100644 (file)
@@ -13,6 +13,7 @@
 typedef enum {
     BOOLEAN,
     INTEGER,
+    FLOAT,
     CHARACTER,
     STRING,
     SEXPR,
index 3b1f391c9aaa6796702362e31add0c7dfec4eb09..0e5dc9334e7e147e5f18e43b9873020381040316 100644 (file)
@@ -1,34 +1,36 @@
-const char Grammar[] = 
-""
-"replexpr : <ws> <expr> /[^\\n]*\\n/ ;"
-""
-"expr : <sexpr> | <qexpr> | <atom> ;"
-""
-"sexpr : '(' (<ws> <expr> <ws>)* ')' ;"
-""
-"qexpr : ('\\'' | '`' | ',') <expr> ;"
-""
-"atom : <float> | <int> | <radixnum> | <ch> | <str> | <bool> | <var> ;"
-""
-"int : /[-+]?[0-9]+/ ;"
-""
-"float : /[-+]?[0-9]+\\.[0-9]+/ ;"
-""
-"radixnum : \"0b\" /[0-1]+/"
-"         | \"0o\" /[0-7]+/"
-"         | \"0d\" /[0-9]+/"
-"         | \"0x\" /[0-9a-fA-F]+/"
-"         ;"
-""
-"ch : '\\\\' (\"space\"|\"newline\"|\"return\"|\"tab\"|\"vtab\")"
-"   | '\\\\' /./"
-"   ;"
-""
-"str : '\"' /[^\"]*/ '\"' ;"
-""
-"bool : \"True\" | \"False\" ;"
-""
-"var : /[^() \\t\\r\\n#`'\"]+/ ;"
-""
-"ws : '#' /[^\\n]*\\n/ | /[ \\t\\r\\n]*/ ;"
-;
+const char Grammar[] = \r
+""\r
+"program : /^/ <expr> /$/ ;"\r
+""\r
+"replexpr : <ws> <expr> /[^\\n]*\\n/ ;"\r
+""\r
+"expr : <sexpr> | <qexpr> | <radixnum> | <float> | <int> | <ch> | <str> | <bool> | <var> ;"\r
+""\r
+"sexpr : '(' (<ws> <expr> <ws>)* ')' ;"\r
+""\r
+"qexpr : ('\\'' | '`' | ',') <expr> ;"\r
+""\r
+"atom : <float> | <int> | <radixnum> | <ch> | <str> | <bool> | <var> ;"\r
+""\r
+"int : /[-+]?[0-9]+/ ;"\r
+""\r
+"float : /[-+]?[0-9]+\\.[0-9]+/ ;"\r
+""\r
+"radixnum : \"0b\" /[0-1]+/"\r
+"         | \"0o\" /[0-7]+/"\r
+"         | \"0d\" /[0-9]+/"\r
+"         | \"0x\" /[0-9a-fA-F]+/"\r
+"         ;"\r
+""\r
+"ch : '\\\\' (\"space\"|\"newline\"|\"return\"|\"tab\"|\"vtab\")"\r
+"   | '\\\\' /./"\r
+"   ;"\r
+""\r
+"str : '\"' /[^\"]*/ '\"' ;"\r
+""\r
+"bool : \"True\" | \"False\" ;"\r
+""\r
+"var : /[^() \\t\\r\\n#`'\"]+/ ;"\r
+""\r
+"ws : '#' /[^\\n]*\\n/ | /[ \\t\\r\\n]*/ ;"\r
+;\r
index 2d1bc6e547921e19569af4d750739ea174930e12..3ed52d938762b9edb92a39a91739e2367f0bcc01 100644 (file)
@@ -1,7 +1,9 @@
 
+program : /^/ <expr> /$/ ;
+
 replexpr : <ws> <expr> /[^\n]*\n/ ;
 
-expr : <sexpr> | <qexpr> | <atom> ;
+expr : <sexpr> | <qexpr> | <radixnum> | <float> | <int> | <ch> | <str> | <bool> | <var> ;
 
 sexpr : '(' (<ws> <expr> <ws>)* ')' ;
 
index 71535b80bc3270de8433bc3af81c75208c46f509..a739c37fb8d5ec45bef372c38063fdcfa2823cca 100644 (file)
@@ -1,39 +1,93 @@
 #include "mpc.h"
 #include "ast.h"
 #include <stdio.h>
+#include <assert.h>
 
 /* SCLPL Parser
  *****************************************************************************/
 /* Grammar is auto generated into 'source/grammar.c' */
 extern const char Grammar[];
 
+static ast_t* read_sexpr(const mpc_ast_t* t) {
+    (void)t;
+    return NULL;
+}
+
+static ast_t* read_qexpr(const mpc_ast_t* t) {
+    (void)t;
+    return NULL;
+}
+
+static ast_t* read_char(const mpc_ast_t* t) {
+    (void)t;
+    return NULL;
+}
+
+static ast_t* read_string(const mpc_ast_t* t) {
+    (void)t;
+    return NULL;
+}
+
+static ast_t* read_var(const mpc_ast_t* t) {
+    (void)t;
+    return NULL;
+}
+
+static ast_t* read_bool(const mpc_ast_t* t) {
+    (void)t;
+    return NULL;
+}
+
+static ast_t* read_float(const mpc_ast_t* t) {
+    double* p_dbl = (double*)malloc(sizeof(double));
+    ast_t* p_ast = ast_new(FLOAT, p_dbl);
+    ast_set_pos(p_ast, "<stdin>", t->state.row, t->state.col);
+    errno = 0;
+    *p_dbl = strtod(t->contents, NULL);
+    assert(errno == 0);
+    return p_ast;
+}
+
+static ast_t* read_int(const mpc_ast_t* t, int base) {
+    long* p_int = (long*)malloc(sizeof(long));
+    printf("reading int with base: %d\n", base);
+    ast_t* p_ast = ast_new(INTEGER, p_int);
+    ast_set_pos(p_ast, "<stdin>", t->state.row, t->state.col);
+    errno = 0;
+    *p_int = strtol(t->contents, NULL, base);
+    assert(errno == 0);
+    return p_ast;
+}
+
+static int read_radix(const mpc_ast_t* t) {
+    switch( t->children[0]->contents[1] ) {
+        case 'b': return 2;
+        case 'o': return 8;
+        case 'd': return 10;
+        case 'x': return 16;
+        default:  return 10;
+    }
+}
+
 ast_t* format_expr_ast(mpc_ast_t* expr) {
-    ast_t* p_ast = ast_new(UNKNOWN,NULL);
-    ast_set_pos(p_ast, "<stdin>", expr->state.row, expr->state.col);
+    ast_t* p_ast = NULL;
 
     /* Handle the current node */
-    if (0 == strcmp("expr|atom|num|regex", expr->tag)) {
-        puts("parsing integer/float");
-    } else if (0 == strcmp("num|>", expr->tag)) {
-        puts("parsing radix literal");
-    } else if (0 == strcmp("str|>", expr->tag)) {
-        puts("parsing string literal");
+    if (0 == strcmp("sexpr|>", expr->tag)) {
+    } else if (0 == strcmp("qexpr|>", expr->tag)) {
+    } else if (0 == strcmp("radixnum|>", expr->tag)) {
+        p_ast = read_int(expr->children[1], read_radix(expr));
+        printf("int: %d\n", *((long*)p_ast->value));
+    } else if (0 == strcmp("expr|float|regex", expr->tag)) {
+        p_ast = read_float(expr);
+        printf("double: %f\n", *((double*)p_ast->value));
+    } else if (0 == strcmp("expr|int|regex", expr->tag)) {
+        p_ast = read_int(expr,10);
+        printf("int: %d\n", *((long*)p_ast->value));
     } else if (0 == strcmp("ch|>", expr->tag)) {
-        puts("parsing char literal");
-    } else if (0 == strcmp("expr|atom|var|regex", expr->tag)) {
-        puts("parsing variable");
-    } else if (0 == strcmp("expr|atom|bool|string", expr->tag)) {
-        puts("parsing boolean");
-    } else if (0 == strcmp("expr|>", expr->tag)) {
-        ast_set_type(p_ast, SEXPR);
-        /* Handle the current node's children */
-        for (int i = 0; i < expr->children_num; i++) {
-            mpc_ast_t* child = expr->children[i];
-            if ((0 != strncmp(child->tag,"ws",2)) &&
-                (0 != strncmp(child->tag,"char",4))) {
-                ast_add_child(p_ast, format_expr_ast(expr->children[i]));
-            }
-        }
+    } else if (0 == strcmp("str|>", expr->tag)) {
+    } else if (0 == strcmp("expr|bool|str", expr->tag)) {
+    } else if (0 == strcmp("expr|var|regex", expr->tag)) {
     } else {
         printf("unknown tag: '%s'\n", expr->tag);
         free(p_ast->pos);
@@ -50,14 +104,16 @@ int main(int argc, char **argv) {
     mpc_parser_t* SExpr = mpc_new("sexpr");
     mpc_parser_t* QExpr = mpc_new("qexpr");
     mpc_parser_t* Atom = mpc_new("atom");
-    mpc_parser_t* Num = mpc_new("num");
+    mpc_parser_t* Int = mpc_new("int");
+    mpc_parser_t* Float = mpc_new("float");
+    mpc_parser_t* Radix = mpc_new("radixnum");
     mpc_parser_t* Char = mpc_new("ch");
     mpc_parser_t* String = mpc_new("str");
     mpc_parser_t* Bool = mpc_new("bool");
     mpc_parser_t* Var = mpc_new("var");
     mpc_parser_t* WS = mpc_new("ws");
     mpca_lang(MPCA_LANG_WHITESPACE_SENSITIVE, Grammar,
-        ReplExpr, Expr, SExpr, QExpr, Atom, Num, Char, String, Bool, Var, WS, NULL);
+        ReplExpr, Expr, SExpr, QExpr, Atom, Int, Float, Radix, Char, String, Bool, Var, WS, NULL);
     while(!feof(stdin)) {
         mpc_result_t r;
         printf(":> ");
@@ -72,6 +128,6 @@ int main(int argc, char **argv) {
             while('\n' != fgetc(stdin)){}
         }
     }
-    mpc_cleanup(11, ReplExpr, Expr, SExpr, QExpr, Atom, Num, Char, String, Bool, Var, WS);
+    mpc_cleanup(13, ReplExpr, Expr, SExpr, QExpr, Atom, Int, Float, Radix, Char, String, Bool, Var, WS);
     return 0;
 }