From 550ca78ae6a7759dc0ca2953dd7454503add2018 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 28 Feb 2009 04:30:56 -0500 Subject: [PATCH] Added some basic compiler stub stuff, just to get this building at all. --- CMakeLists.txt | 13 ++++ mojoshader_compiler.c | 142 ++++++++++++++++++++++++++++++++++++ utils/mojoshader-compiler.c | 31 ++++++++ 3 files changed, 186 insertions(+) create mode 100644 mojoshader_compiler.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ac6a61c..f3adec0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,8 +50,21 @@ IF(MSVC) 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 diff --git a/mojoshader_compiler.c b/mojoshader_compiler.c new file mode 100644 index 00000000..71bac4e2 --- /dev/null +++ b/mojoshader_compiler.c @@ -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); +} + diff --git a/utils/mojoshader-compiler.c b/utils/mojoshader-compiler.c index a904236c..3b9abace 100644 --- a/utils/mojoshader-compiler.c +++ b/utils/mojoshader-compiler.c @@ -190,12 +190,34 @@ static int assemble(const char *fname, const char *buf, int len, 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 @@ int main(int argc, char **argv) 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 @@ int main(int argc, char **argv) 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);