added util/refptr, tests/Initial.jtl, parser/parser.h, c_statement to grammar
git-svn-id: svn://anubis/jtlc/trunk@7 f5bc74b8-7b62-4e90-9214-7121d538519f
This commit is contained in:
parent
bb982b62b8
commit
c9c59e41fc
5
Makefile
5
Makefile
@ -2,10 +2,11 @@
|
|||||||
SHELL := bash
|
SHELL := bash
|
||||||
TARGET := jtlc
|
TARGET := jtlc
|
||||||
ifdef WIN32
|
ifdef WIN32
|
||||||
export CPPFLAGS += -I"$(shell cd)"
|
TOPLEVEL := $(shell cd)
|
||||||
else
|
else
|
||||||
export CPPFLAGS += -I"$(shell pwd)"
|
TOPLEVEL := $(shell pwd)
|
||||||
endif
|
endif
|
||||||
|
export CPPFLAGS += -I"$(TOPLEVEL)"
|
||||||
export CXXFLAGS := -Wall -O2
|
export CXXFLAGS := -Wall -O2
|
||||||
|
|
||||||
LDFLAGS := -lfl
|
LDFLAGS := -lfl
|
||||||
|
42
main/jtlc.cc
42
main/jtlc.cc
@ -1,8 +1,46 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h> /* tmpfile() */
|
||||||
|
#include <stdlib.h> /* exit() */
|
||||||
|
#include "parser/parser.h"
|
||||||
|
#include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int usage();
|
||||||
|
void compile(const char * filename);
|
||||||
|
|
||||||
|
int usage()
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: jtlc [options] <source files>\n");
|
||||||
|
exit(42);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char * argv[])
|
int main(int argc, char * argv[])
|
||||||
{
|
{
|
||||||
printf("jtlc, version 0.00000001\n");
|
vector<const char *> 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void compile(const char * filename)
|
||||||
|
{
|
||||||
|
FILE * out = tmpfile();
|
||||||
|
parse(filename);
|
||||||
|
fclose(out);
|
||||||
|
}
|
||||||
|
9
parser/parser.h
Normal file
9
parser/parser.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
#ifndef PARSER_H
|
||||||
|
#define PARSER_H
|
||||||
|
|
||||||
|
#include "util/refptr.h"
|
||||||
|
|
||||||
|
void parse(const char * fileName);
|
||||||
|
|
||||||
|
#endif
|
@ -75,6 +75,7 @@ float return FLOAT;
|
|||||||
double return DOUBLE;
|
double return DOUBLE;
|
||||||
|
|
||||||
/* keywords */
|
/* keywords */
|
||||||
|
c return C;
|
||||||
import return IMPORT;
|
import return IMPORT;
|
||||||
module return MODULE;
|
module return MODULE;
|
||||||
return return RETURN;
|
return return RETURN;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "parser.tab.hh" /* bison-generated header with YY[SL]TYPE */
|
#include "parser.tab.hh" /* bison-generated header with YY[SL]TYPE */
|
||||||
|
#include "parser.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#define yyerror(msg) errFunc(msg, &yylloc)
|
#define yyerror(msg) errFunc(msg, &yylloc)
|
||||||
@ -76,6 +77,7 @@ int yywrap()
|
|||||||
%token DOUBLE;
|
%token DOUBLE;
|
||||||
|
|
||||||
/* keywords */
|
/* keywords */
|
||||||
|
%token C;
|
||||||
%token IMPORT;
|
%token IMPORT;
|
||||||
%token MODULE;
|
%token MODULE;
|
||||||
%token RETURN;
|
%token RETURN;
|
||||||
@ -94,6 +96,7 @@ program_item: module_declaration
|
|||||||
| import
|
| import
|
||||||
| variable_declaration
|
| variable_declaration
|
||||||
| function
|
| function
|
||||||
|
| c_statement
|
||||||
;
|
;
|
||||||
|
|
||||||
module_declaration: MODULE module_name SEMICOLON
|
module_declaration: MODULE module_name SEMICOLON
|
||||||
@ -177,10 +180,11 @@ type: primitive_type
|
|||||||
;
|
;
|
||||||
|
|
||||||
statement: expression SEMICOLON
|
statement: expression SEMICOLON
|
||||||
| return_statement SEMICOLON
|
| return_statement
|
||||||
|
| c_statement
|
||||||
;
|
;
|
||||||
|
|
||||||
return_statement: RETURN expression
|
return_statement: RETURN expression SEMICOLON
|
||||||
;
|
;
|
||||||
|
|
||||||
expression: assign_expr
|
expression: assign_expr
|
||||||
@ -193,6 +197,10 @@ assign_expr: lvalue ASSIGN expression
|
|||||||
lvalue: IDENTIFIER
|
lvalue: IDENTIFIER
|
||||||
;
|
;
|
||||||
|
|
||||||
|
c_statement: C LPAREN STRING_LITERAL RPAREN SEMICOLON {
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
void parse(const char * fileName)
|
void parse(const char * fileName)
|
||||||
|
0
tests/Initial.jtl
Normal file
0
tests/Initial.jtl
Normal file
106
util/refptr.h
Normal file
106
util/refptr.h
Normal file
@ -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 <stdlib.h> /* NULL */
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class refptr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
refptr<T>();
|
||||||
|
refptr<T>(T * ptr);
|
||||||
|
refptr<T>(const refptr<T> & orig);
|
||||||
|
refptr<T> & operator=(const refptr<T> & orig);
|
||||||
|
refptr<T> & operator=(T * ptr);
|
||||||
|
~refptr<T>();
|
||||||
|
T & operator*() const;
|
||||||
|
T * operator->() const;
|
||||||
|
bool isNull() const { return m_ptr == NULL; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void cloneFrom(const refptr<T> & orig);
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
T * m_ptr;
|
||||||
|
int * m_refCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> refptr<T>::refptr()
|
||||||
|
{
|
||||||
|
m_ptr = NULL;
|
||||||
|
m_refCount = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> refptr<T>::refptr(T * ptr)
|
||||||
|
{
|
||||||
|
m_ptr = ptr;
|
||||||
|
m_refCount = new int;
|
||||||
|
*m_refCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> refptr<T>::refptr(const refptr<T> & orig)
|
||||||
|
{
|
||||||
|
cloneFrom(orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> refptr<T> & refptr<T>::operator=(const refptr<T> & orig)
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
cloneFrom(orig);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> refptr<T> & refptr<T>::operator=(T * ptr)
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
m_ptr = ptr;
|
||||||
|
m_refCount = new int;
|
||||||
|
*m_refCount = 1;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void refptr<T>::cloneFrom(const refptr<T> & orig)
|
||||||
|
{
|
||||||
|
this->m_ptr = orig.m_ptr;
|
||||||
|
this->m_refCount = orig.m_refCount;
|
||||||
|
if (m_refCount != NULL)
|
||||||
|
(*m_refCount)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> refptr<T>::~refptr()
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void refptr<T>::destroy()
|
||||||
|
{
|
||||||
|
if (m_refCount != NULL)
|
||||||
|
{
|
||||||
|
if (*m_refCount <= 1)
|
||||||
|
{
|
||||||
|
delete m_ptr;
|
||||||
|
delete m_refCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*m_refCount)--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> T & refptr<T>::operator*() const
|
||||||
|
{
|
||||||
|
return *m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> T * refptr<T>::operator->() const
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user