diff --git a/Makefile b/Makefile index 840d0e6..ee32337 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,11 @@ SHELL := bash TARGET := jtlc ifdef WIN32 -export CPPFLAGS += -I"$(shell cd)" +TOPLEVEL := $(shell cd) else -export CPPFLAGS += -I"$(shell pwd)" +TOPLEVEL := $(shell pwd) endif +export CPPFLAGS += -I"$(TOPLEVEL)" export CXXFLAGS := -Wall -O2 LDFLAGS := -lfl diff --git a/main/jtlc.cc b/main/jtlc.cc index 5f5a0a2..933afc6 100644 --- a/main/jtlc.cc +++ b/main/jtlc.cc @@ -1,8 +1,46 @@ -#include +#include /* tmpfile() */ +#include /* exit() */ +#include "parser/parser.h" +#include +using namespace std; + +int usage(); +void compile(const char * filename); + +int usage() +{ + fprintf(stderr, "Usage: jtlc [options] \n"); + exit(42); +} int main(int argc, char * argv[]) { - printf("jtlc, version 0.00000001\n"); + vector source_files; + for (int i = 1; i < argc; i++) + { + if (argv[i][0] != '-') + { + source_files.push_back(argv[i]); + } + } + + if (source_files.size() < 1) + { + usage(); + } + + for (int i = 0, num = source_files.size(); i < num; i++) + { + compile(source_files[i]); + } + return 0; } + +void compile(const char * filename) +{ + FILE * out = tmpfile(); + parse(filename); + fclose(out); +} diff --git a/parser/parser.h b/parser/parser.h new file mode 100644 index 0000000..522ac56 --- /dev/null +++ b/parser/parser.h @@ -0,0 +1,9 @@ + +#ifndef PARSER_H +#define PARSER_H + +#include "util/refptr.h" + +void parse(const char * fileName); + +#endif diff --git a/parser/parser.lex b/parser/parser.lex index d39b5a8..ed33fe9 100644 --- a/parser/parser.lex +++ b/parser/parser.lex @@ -75,6 +75,7 @@ float return FLOAT; double return DOUBLE; /* keywords */ +c return C; import return IMPORT; module return MODULE; return return RETURN; diff --git a/parser/parser.yy b/parser/parser.yy index d7a3968..56f8f80 100644 --- a/parser/parser.yy +++ b/parser/parser.yy @@ -4,6 +4,7 @@ #include #include #include "parser.tab.hh" /* bison-generated header with YY[SL]TYPE */ +#include "parser.h" using namespace std; #define yyerror(msg) errFunc(msg, &yylloc) @@ -76,6 +77,7 @@ int yywrap() %token DOUBLE; /* keywords */ +%token C; %token IMPORT; %token MODULE; %token RETURN; @@ -94,6 +96,7 @@ program_item: module_declaration | import | variable_declaration | function + | c_statement ; module_declaration: MODULE module_name SEMICOLON @@ -177,10 +180,11 @@ type: primitive_type ; statement: expression SEMICOLON - | return_statement SEMICOLON + | return_statement + | c_statement ; -return_statement: RETURN expression +return_statement: RETURN expression SEMICOLON ; expression: assign_expr @@ -193,6 +197,10 @@ assign_expr: lvalue ASSIGN expression lvalue: IDENTIFIER ; +c_statement: C LPAREN STRING_LITERAL RPAREN SEMICOLON { + } + ; + %% void parse(const char * fileName) diff --git a/tests/Initial.jtl b/tests/Initial.jtl new file mode 100644 index 0000000..e69de29 diff --git a/util/refptr.h b/util/refptr.h new file mode 100644 index 0000000..7e6ecf8 --- /dev/null +++ b/util/refptr.h @@ -0,0 +1,106 @@ +/* + * Author: Josh Holtrop + * Purpose: Provide a reference-counting "pointer" object for C++ + */ + +#ifndef REFPTR_H +#define REFPTR_H REFPTR_H + +#include /* NULL */ + +template +class refptr +{ + public: + refptr(); + refptr(T * ptr); + refptr(const refptr & orig); + refptr & operator=(const refptr & orig); + refptr & operator=(T * ptr); + ~refptr(); + T & operator*() const; + T * operator->() const; + bool isNull() const { return m_ptr == NULL; } + + private: + void cloneFrom(const refptr & orig); + void destroy(); + + T * m_ptr; + int * m_refCount; +}; + +template refptr::refptr() +{ + m_ptr = NULL; + m_refCount = NULL; +} + +template refptr::refptr(T * ptr) +{ + m_ptr = ptr; + m_refCount = new int; + *m_refCount = 1; +} + +template refptr::refptr(const refptr & orig) +{ + cloneFrom(orig); +} + +template refptr & refptr::operator=(const refptr & orig) +{ + destroy(); + cloneFrom(orig); + return *this; +} + +template refptr & refptr::operator=(T * ptr) +{ + destroy(); + m_ptr = ptr; + m_refCount = new int; + *m_refCount = 1; + return *this; +} + +template void refptr::cloneFrom(const refptr & orig) +{ + this->m_ptr = orig.m_ptr; + this->m_refCount = orig.m_refCount; + if (m_refCount != NULL) + (*m_refCount)++; +} + +template refptr::~refptr() +{ + destroy(); +} + +template void refptr::destroy() +{ + if (m_refCount != NULL) + { + if (*m_refCount <= 1) + { + delete m_ptr; + delete m_refCount; + } + else + { + (*m_refCount)--; + } + } +} + +template T & refptr::operator*() const +{ + return *m_ptr; +} + +template T * refptr::operator->() const +{ + return m_ptr; +} + +#endif