Added some basic compiler stub stuff, just to get this building at all.
authorRyan C. Gordon <icculus@icculus.org>
Sat, 28 Feb 2009 04:30:56 -0500
changeset 706 01a92f30b84f
parent 705 7ea12a852213
child 707 85b648e14089
Added some basic compiler stub stuff, just to get this building at all.
CMakeLists.txt
mojoshader_compiler.c
utils/mojoshader-compiler.c
--- a/CMakeLists.txt	Sat Feb 28 04:29:40 2009 -0500
+++ b/CMakeLists.txt	Sat Feb 28 04:30:56 2009 -0500
@@ -50,8 +50,21 @@
     ADD_DEFINITIONS(-TP)  # force .c files to compile as C++.
 ENDIF(MSVC)
 
+# We build lemon, then use it to generate parser C code.
+ADD_EXECUTABLE(lemon "misc/lemon.c")
+GET_TARGET_PROPERTY(LEMON lemon LOCATION)
+ADD_CUSTOM_COMMAND(
+    OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/mojoshader_parser_hlsl.c" "${CMAKE_CURRENT_SOURCE_DIR}/mojoshader_parser_hlsl.h"
+    MAIN_DEPENDENCY mojoshader_parser_hlsl.lemon
+    DEPENDS lemon
+    WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/misc"
+    COMMAND "${LEMON}"
+    ARGS -l -q "${CMAKE_CURRENT_SOURCE_DIR}/mojoshader_parser_hlsl.lemon"
+)
+
 ADD_LIBRARY(mojoshader STATIC
     mojoshader.c
+    mojoshader_compiler.c
     mojoshader_preprocessor.c
     mojoshader_lexer.c
     mojoshader_assembler.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mojoshader_compiler.c	Sat Feb 28 04:30:56 2009 -0500
@@ -0,0 +1,142 @@
+typedef struct Context Context;
+#include "mojoshader_parser_hlsl.h"
+#include "mojoshader_parser_hlsl.c"
+
+struct Context
+{
+    Preprocessor *preprocessor;
+    const char *token;      // assembler token!
+    unsigned int tokenlen;  // assembler token!
+    Token tokenval;         // assembler token!
+};
+
+static int ConvertToLemonToken(const Context *ctx)
+{
+    switch (ctx->tokenval)
+    {
+        case ((Token) ','): return TOKEN_HLSL_COMMA;
+        case ((Token) '='): return TOKEN_HLSL_ASSIGN;
+        case ((Token) TOKEN_ADDASSIGN): return TOKEN_HLSL_ADDASSIGN;
+        case ((Token) TOKEN_SUBASSIGN): return TOKEN_HLSL_SUBASSIGN;
+        case ((Token) TOKEN_MULTASSIGN): return TOKEN_HLSL_MULASSIGN;
+        case ((Token) TOKEN_DIVASSIGN): return TOKEN_HLSL_DIVASSIGN;
+        case ((Token) TOKEN_MODASSIGN): return TOKEN_HLSL_MODASSIGN;
+        case ((Token) TOKEN_LSHIFTASSIGN): return TOKEN_HLSL_LSHIFTASSIGN;
+        case ((Token) TOKEN_RSHIFTASSIGN): return TOKEN_HLSL_RSHIFTASSIGN;
+        case ((Token) TOKEN_ANDASSIGN): return TOKEN_HLSL_ANDASSIGN;
+        case ((Token) TOKEN_ORASSIGN): return TOKEN_HLSL_ORASSIGN;
+        case ((Token) TOKEN_XORASSIGN): return TOKEN_HLSL_XORASSIGN;
+        case ((Token) '?'): return TOKEN_HLSL_QUESTION;
+        case ((Token) TOKEN_OROR): return TOKEN_HLSL_OROR;
+        case ((Token) TOKEN_ANDAND): return TOKEN_HLSL_ANDAND;
+        case ((Token) '|'): return TOKEN_HLSL_OR;
+        case ((Token) '^'): return TOKEN_HLSL_XOR;
+        case ((Token) '&'): return TOKEN_HLSL_AND;
+        case ((Token) TOKEN_EQL): return TOKEN_HLSL_EQL;
+        case ((Token) TOKEN_NEQ): return TOKEN_HLSL_NEQ;
+        case ((Token) '<'): return TOKEN_HLSL_LT;
+        case ((Token) TOKEN_LEQ): return TOKEN_HLSL_LEQ;
+        case ((Token) '>'): return TOKEN_HLSL_GT;
+        case ((Token) TOKEN_GEQ): return TOKEN_HLSL_GEQ;
+        case ((Token) TOKEN_LSHIFT): return TOKEN_HLSL_LSHIFT;
+        case ((Token) TOKEN_RSHIFT): return TOKEN_HLSL_RSHIFT;
+        case ((Token) '+'): return TOKEN_HLSL_PLUS;
+        case ((Token) '-'): return TOKEN_HLSL_MINUS;
+        case ((Token) '*'): return TOKEN_HLSL_STAR;
+        case ((Token) '/'): return TOKEN_HLSL_SLASH;
+        case ((Token) '%'): return TOKEN_HLSL_PERCENT;
+        case ((Token) '!'): return TOKEN_HLSL_EXCLAMATION;
+        case ((Token) '~'): return TOKEN_HLSL_COMPLEMENT;
+        case ((Token) TOKEN_DECREMENT): return TOKEN_HLSL_MINUSMINUS;
+        case ((Token) TOKEN_INCREMENT): return TOKEN_HLSL_PLUSPLUS;
+        case ((Token) '.'): return TOKEN_HLSL_DOT;
+        case ((Token) '['): return TOKEN_HLSL_LBRACKET;
+        case ((Token) ']'): return TOKEN_HLSL_RBRACKET;
+        case ((Token) '('): return TOKEN_HLSL_LPAREN;
+        case ((Token) ')'): return TOKEN_HLSL_RPAREN;
+        case ((Token) TOKEN_INT_LITERAL): return TOKEN_HLSL_CONSTANT;
+        case ((Token) TOKEN_FLOAT_LITERAL): return TOKEN_HLSL_CONSTANT;
+        case ((Token) TOKEN_STRING_LITERAL): return TOKEN_HLSL_STRING_LITERAL;
+        case ((Token) ':'): return TOKEN_HLSL_COLON;
+        case ((Token) ';'): return TOKEN_HLSL_SEMICOLON;
+        case ((Token) '{'): return TOKEN_HLSL_LBRACE;
+        case ((Token) '}'): return TOKEN_HLSL_RBRACE;
+
+        case ((Token) TOKEN_IDENTIFIER):
+            #define tokencmp(t) ((ctx->tokenlen == strlen(t)) && (memcmp(ctx->token, t, ctx->tokenlen) == 0))
+            //case ((Token) ''): return TOKEN_HLSL_TYPECAST
+            //if (tokencmp("")) return TOKEN_HLSL_TYPE_NAME
+            //if (tokencmp("...")) return TOKEN_HLSL_ELIPSIS
+            if (tokencmp("else")) return TOKEN_HLSL_ELSE;
+            if (tokencmp("sizeof")) return TOKEN_HLSL_SIZEOF;
+            if (tokencmp("typedef")) return TOKEN_HLSL_TYPEDEF;
+            if (tokencmp("extern")) return TOKEN_HLSL_EXTERN;
+            if (tokencmp("static")) return TOKEN_HLSL_STATIC;
+            if (tokencmp("auto")) return TOKEN_HLSL_AUTO;
+            if (tokencmp("register")) return TOKEN_HLSL_REGISTER;
+            if (tokencmp("char")) return TOKEN_HLSL_CHAR;
+            if (tokencmp("short")) return TOKEN_HLSL_SHORT;
+            if (tokencmp("int")) return TOKEN_HLSL_INT;
+            if (tokencmp("long")) return TOKEN_HLSL_LONG;
+            if (tokencmp("signed")) return TOKEN_HLSL_SIGNED;
+            if (tokencmp("unsigned")) return TOKEN_HLSL_UNSIGNED;
+            if (tokencmp("float")) return TOKEN_HLSL_FLOAT;
+            if (tokencmp("double")) return TOKEN_HLSL_DOUBLE;
+            if (tokencmp("const")) return TOKEN_HLSL_CONST;
+            if (tokencmp("volatile")) return TOKEN_HLSL_VOLATILE;
+            if (tokencmp("void")) return TOKEN_HLSL_VOID;
+            if (tokencmp("struct")) return TOKEN_HLSL_STRUCT;
+            if (tokencmp("union")) return TOKEN_HLSL_UNION;
+            if (tokencmp("enum")) return TOKEN_HLSL_ENUM;
+            if (tokencmp("case")) return TOKEN_HLSL_CASE;
+            if (tokencmp("default")) return TOKEN_HLSL_DEFAULT;
+            if (tokencmp("if")) return TOKEN_HLSL_IF;
+            if (tokencmp("switch")) return TOKEN_HLSL_SWITCH;
+            if (tokencmp("while")) return TOKEN_HLSL_WHILE;
+            if (tokencmp("do")) return TOKEN_HLSL_DO;
+            if (tokencmp("for")) return TOKEN_HLSL_FOR;
+            if (tokencmp("goto")) return TOKEN_HLSL_GOTO;
+            if (tokencmp("continue")) return TOKEN_HLSL_CONTINUE;
+            if (tokencmp("break")) return TOKEN_HLSL_BREAK;
+            if (tokencmp("return")) return TOKEN_HLSL_RETURN;
+            #undef tokencmp
+            return TOKEN_HLSL_IDENTIFIER;
+
+        case TOKEN_EOI: return 0;
+        case TOKEN_BAD_CHARS: printf("bad chars from lexer\n"); return 0;
+        case TOKEN_PREPROCESSING_ERROR: printf("error from lexer\n"); return 0;
+        default: assert(0 && "unexpected token from lexer\n"); return 0;
+    } // switch
+
+    return 0;
+}
+
+
+void MOJOSHADER_compile(const char *filename,
+                             const char *source, unsigned int sourcelen,
+                             const MOJOSHADER_preprocessorDefine *defines,
+                             unsigned int define_count,
+                             MOJOSHADER_includeOpen include_open,
+                             MOJOSHADER_includeClose include_close,
+                             MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
+{
+    Context ctx;
+    if (m == NULL) m = MOJOSHADER_internal_malloc;
+    if (f == NULL) f = MOJOSHADER_internal_free;
+    
+    ctx.preprocessor = preprocessor_start(filename, source, sourcelen,
+                                           include_open, include_close,
+                                           defines, define_count, 0, m, f, d);
+
+    void *pParser = ParseHLSLAlloc(m, d);
+    ParseHLSLTrace(stdout, "TRACE: ");
+
+    do {
+        ctx.token = preprocessor_nexttoken(ctx.preprocessor,
+                                                &ctx.tokenlen,
+                                                &ctx.tokenval);
+        ParseHLSL(pParser, ConvertToLemonToken(&ctx), 0, 0);
+    } while (ctx.tokenval != TOKEN_EOI);
+    ParseHLSLFree(pParser, f, d);
+}
+
--- a/utils/mojoshader-compiler.c	Sat Feb 28 04:29:40 2009 -0500
+++ b/utils/mojoshader-compiler.c	Sat Feb 28 04:30:56 2009 -0500
@@ -190,12 +190,34 @@
     return retval;
 } // assemble
 
+void MOJOSHADER_compile(const char *filename,
+                             const char *source, unsigned int sourcelen,
+                             const MOJOSHADER_preprocessorDefine *defines,
+                             unsigned int define_count,
+                             MOJOSHADER_includeOpen include_open,
+                             MOJOSHADER_includeClose include_close,
+                             MOJOSHADER_malloc m, MOJOSHADER_free f, void *d);
+
+static int compile(const char *fname, const char *buf, int len,
+                    const char *outfile,
+                    const MOJOSHADER_preprocessorDefine *defs,
+                    unsigned int defcount, FILE *io)
+{
+    const MOJOSHADER_parseData *pd;
+    int retval = 0;
+
+    MOJOSHADER_compile(fname, buf, len, defs, defcount,
+                             open_include, close_include,
+                             Malloc, Free, NULL);
+    return 1;
+} // compile
 
 typedef enum
 {
     ACTION_UNKNOWN,
     ACTION_PREPROCESS,
     ACTION_ASSEMBLE,
+    ACTION_COMPILE,
 } Action;
 
 
@@ -232,6 +254,13 @@
             action = ACTION_ASSEMBLE;
         } // else if
 
+        else if (strcmp(arg, "-C") == 0)
+        {
+            if ((action != ACTION_UNKNOWN) && (action != ACTION_COMPILE))
+                fail("Multiple actions specified");
+            action = ACTION_COMPILE;
+        } // else if
+
         else if (strcmp(arg, "-o") == 0)
         {
             if (outfile != NULL)
@@ -312,6 +341,8 @@
         retval = (!preprocess(infile, buf, rc, outfile, defs, defcount, outio));
     else if (action == ACTION_ASSEMBLE)
         retval = (!assemble(infile, buf, rc, outfile, defs, defcount, outio));
+    else if (action == ACTION_COMPILE)
+        retval = (!compile(infile, buf, rc, outfile, defs, defcount, outio));
 
     if ((retval != 0) && (outfile != NULL))
         remove(outfile);