diff options
| Commit | 7cc99d560d3f36996dde0f73becd57445fc54d11 (patch) | |
|---|---|---|
| Author | 2023-02-08 12:34:27 +0200 | |
| Committer | 2023-02-08 12:34:27 +0200 | |
| Files | 8284219e1186a554cf5050194e72a18708c6cdee | |
| uni-projects-7cc99d560d3f36996dde0f73becd57445fc54d11.tar uni-projects-7cc99d560d3f36996dde0f73becd57445fc54d11.tar.gz uni-projects-7cc99d560d3f36996dde0f73becd57445fc54d11.zip | ||
| Parent | 90d86e8072e7246374076961a26cfd1024ac67f7 (diff) | |
[IPL/T] Added unfinished makefile and frontend
4 files changed, 175 insertions, 23 deletions
diff --git a/Year 2/Implementation of Programming Languages/Transpiler/Makefile b/Year 2/Implementation of Programming Languages/Transpiler/Makefile new file mode 100644 index 0000000..52c45ab --- /dev/null +++ b/Year 2/Implementation of Programming Languages/Transpiler/Makefile @@ -0,0 +1,37 @@ +CC=gcc +CFLAGS= +CXX=g++ +CXXFLAGS= +LEX=flex +YACC=bison + +.PHONY: all +all: build-frontend run-frontend build-transpiler run-transpiler + +.PHONY: build-frontend +build-frontend: build-parser build-lexer + cd build && $(CC) lex.yy.c commonlisp2transpilerstr.tab.c $(CFLAGS) -o frontend.out + +.PHONY: build-lexer +build-lexer: + cd frontend && $(LEX) commonlisp2transpilerstr.l && mkdir -p ../build/ && mv lex.yy.c ../build/ + +.PHONY: build-parser +build-parser: + cd frontend && $(YACC) commonlisp2transpilerstr.y && mkdir -p ../build/ && mv commonlisp2transpilerstr.tab.c ../build/ + +.PHONY: run-frontend +run-frontend: + cd build/ && frontend.out < ../src.cl >> CLtree.h + +.PHONY: build-transpiler +build-transpiler: + cd src/ && $(CXX) *.cpp */*.cpp $(CXXFLAGS) -o cltranspiler.out && mkdir -p ../build/ && mv cltranspiler.out ../build/ + +.PHONY: run-transpiler +run-transpiler: + cd build/ && ./cltranspiler.out && mv transpiled.ll .. + +.PHONY: tests +tests: + cd tests && $(CXX) 'Tests_ALL.cpp' ../src/*/*.cpp $(CXXFLAGS) && ./a.out diff --git a/Year 2/Implementation of Programming Languages/Transpiler/frontend/commonlisp2transpilerstr.l b/Year 2/Implementation of Programming Languages/Transpiler/frontend/commonlisp2transpilerstr.l new file mode 100644 index 0000000..d2bffba --- /dev/null +++ b/Year 2/Implementation of Programming Languages/Transpiler/frontend/commonlisp2transpilerstr.l @@ -0,0 +1,30 @@ +%{ +#include "../build/commonlisp2transpilerstr.tab.h" +%} + +DIGIT [0-9] +LEFTBRACKET \( +RIGHTBRACKET \) + +/* STR \"([^\"]|\\\")*([^\\]|\\\\)\" */ +INTEGER (\+|-)?{DIGIT} +FLOAT {INTEGER}(\.{DIGIT}+(e{DIGIT}+|d{DIGIT}+|e-{DIGIT}+)?|\/{DIGIT}+)? + +COMMENT ;.*$ + +FUNCTION "+ "|"- "|"* "|\/|defun|defvar|if|=|>|>=|<|<= + +%% + +{LEFTBRACKET} { return LBRACKET; } +{RIGHTBRACKET} { return RBRACKET; } +/* {STR} { yylval = strdup(yytext); return STR; } */ +{INTEGER} { yylval = strdup(yytext); return INTEGER; } +{FLOAT} { yylval = strdup(yytext); return FLOAT;} + +{FUNCTION} { yylval = strdup(yytext); return FUNCTION; } + + /* flex catches the longest possibility, so if some variable name contains a known word (function, macro, etc.), this will prevent it from highlighting */ +[A-z!-'*-@]+|" "|\t { yylval = strdup(yytext); return NAME; } + +%% diff --git a/Year 2/Implementation of Programming Languages/Transpiler/frontend/commonlisp2transpilerstr.y b/Year 2/Implementation of Programming Languages/Transpiler/frontend/commonlisp2transpilerstr.y new file mode 100644 index 0000000..04c58bd --- /dev/null +++ b/Year 2/Implementation of Programming Languages/Transpiler/frontend/commonlisp2transpilerstr.y @@ -0,0 +1,106 @@ +%{ +#include <stdio.h> +#include <string.h> + +int yylex(); +int yyerror(char *s); +%} + +%token LBRACKET RBRACKET NAME +%token INTEGER FLOAT FUNCTION + +%define api.value.type {char*} + +%% + +start: + | LBRACKET FUNCTION namelist + +namelist: + | LBRACKET RBRACKET + | LBRACKET +start: + | start stlist { printf("%s", $2); free($2); } + | start terminal { printf("%s", $2); free($2); } + | start NEWLINE { printf("\n"); } + +stlist: LBRACKET RBRACKET { $$ = concat2(LBRACKET_SPAN, RBRACKET_SPAN); } + | LBRACKET list RBRACKET { $$ = concatperm3(LBRACKET_SPAN, $2, RBRACKET_SPAN); } + | LBRACKET NEWLINE list RBRACKET { $$ = details(concat2(LBRACKET_SPAN, ""), $3); } + | LBRACKET list NEWLINE postlist RBRACKET { $$ = details($2, $4); } + ; + +postlist: { $$ = ""; } + | postlist stlist { $$ = concat2($1, $2); free($2); } + | postlist terminal { $$ = concat2($1, $2); free($2); } + | postlist NEWLINE { $$ = concat2($1, "\n"); } + ; + +list: terminal + | list terminal { $$ = concatperm2($1, $2); } + | stlist + | list stlist { $$ = concatperm2($1, $2); } + ; + +terminal: STR { $$ = span("string", $1); } + | NUM { $$ = span("number", $1); } + | COMMENT { $$ = span("comment", $1); } + | PARAMETER_TYPE { $$ = span("parameter-type", $1); } + | KEYWORD { $$ = span("keyword", $1); } + | CONSTANT { $$ = span("constant", $1); } + | SPECIAL_FORM { $$ = span("special-operator", $1); } + | FUNCTION { $$ = span("function", $1); } + | MACRO { $$ = span("macro", $1); } + | VARIABLE { $$ = span("variable", $1); } + | OTHER { $$ = span("", $1); } + ; + +%% + + +char* span(char *c, char *s) { + char* str = (char*)malloc(strlen(c) + strlen(s) + 1 + 22); + sprintf(str, "<span class=\"%s\">%s</span>", c, s); + free(s); + return str; +} +char* details(char *summary, char *rest) { + if (*rest == '\0') rest = concat2("", ""); // Зверски грозен фикс, но не е толкова голям проблем + + char* str = (char*)malloc(strlen(LBRACKET_SPAN) + strlen(summary) + strlen(rest) + strlen(RBRACKET_SPAN) + 1 + 39); + sprintf(str, "<details><summary>%s%s</summary>\n%s%s</details>", LBRACKET_SPAN, summary, rest, RBRACKET_SPAN); + + free(summary); free(rest); + return str; +} + +char* concat2(char* first, char* second) { + char* concat = (char*)malloc(strlen(first) + strlen(second) + 1); + sprintf(concat, "%s%s", first, second); + return concat; +} +char* concatperm2(char *first, char *second) { + char* concat = concat2(first, second); + free(first); free(second); + return concat; +} + +char* concatperm3(char *first, char *second, char *third) { + char* concat = (char*)malloc(strlen(first) + strlen(second) + strlen(third) + 1); + sprintf(concat, "%s%s%s", first, second, third); + free(second); + return concat; +} + + +int yyerror(char *s) { + printf("Error: %s\n", s); + return 0; +} + +int main(int argc, char **argv) { +/* #ifdef YYDEBUG */ +/* yydebug = 1; */ +/* #endif */ + yyparse(); +} diff --git a/Year 2/Implementation of Programming Languages/Transpiler/src/main.cpp b/Year 2/Implementation of Programming Languages/Transpiler/src/main.cpp index bc651e6..e382161 100644 --- a/Year 2/Implementation of Programming Languages/Transpiler/src/main.cpp +++ b/Year 2/Implementation of Programming Languages/Transpiler/src/main.cpp @@ -17,33 +17,12 @@ void freeNodes(Value* v) { int main() { LLVMVisitor visitor("testout.ll"); std::deque<Value*> nodes = { - new Funcall("defvar", { - new Name("myvar"), - new Integer(19) - }), - new Funcall("+", { - new Float(1), - new Funcall("-", { new Float(5), new Float(10) }), - new Float(2), - new Float(123) }), - new Funcall("defun", { - new Name("notfun"), - new List({new Name("a"), new Name("b")}), - new Funcall("+", { - new Integer(7), - new Name("a"), - new Name("b") - }), - new Funcall("if", { - new Funcall(">=", { new Integer(5), new Integer(6) }), - new Funcall("+", { new Integer(1), new Integer(2) }), - new Funcall("-", { new Integer(3), new Integer(4) }) - })}) + new Funcall("defvar", { new Name("myvar"), new Float(4.956) }) }; for (Value* n : nodes) { n->Visit(visitor); } - visitor.insertMain(); + // visitor.insertMain(); for (Value* n : nodes) freeNodes(n); |
