Commit b1e7c7fd authored by Sarah Spall's avatar Sarah Spall Committed by Vikram Narayanan

new and improved Makefile, updated RootScope map to use string instead of char*

parent f0511184
.PHONY: clean test
compiler: lcd_ast.o main.o lcd_idl.o scope.o
g++ lcd_idl.o lcd_ast.o scope.o main.o -o compiler
bin = compiler
idl = parser/lcd_idl.cpp include/lcd_idl.h
main.o: main/main.cpp include/lcd_ast.h lcd_idl.h
g++ -c -g main/main.cpp
CXXFLAGS = -g -Iinclude/
CXX = g++
lcd_idl.o: lcd_idl.h include/lcd_ast.h lcd_idl.cpp
g++ -c parser/lcd_idl.cpp
objects = lcd_ast.o main.o lcd_idl.o scope.o header_gen.o
scope.o: include/lcd_ast.h ast/scope.cpp
g++ -c ast/scope.cpp include/lcd_ast.h
$(bin): $(objects)
$(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS)
lcd_ast.o: include/lcd_ast.h ast/lcd_ast.cpp
g++ -c ast/lcd_ast.cpp include/lcd_ast.h
main.o: main/main.cpp include/lcd_ast.h include/lcd_idl.h include/gen_visitor.h
$(CXX) $(CXXFLAGS) -c -o $@ $(filter-out %.h,$^)
lcd_idl.h:
parser/vembyr-1.1/peg.py --h parser/lcd_idl.peg > parser/lcd_idl.h
header_gen.o: gen/header_gen.cpp include/gen_visitor.h
$(CXX) $(CXXFLAGS) -c -o $@ $(filter-out %.h,$^)
lcd_idl.cpp:
parser/vembyr-1.1/peg.py --cpp parser/lcd_idl.peg > parser/lcd_idl.cpp
lcd_idl.o: $(idl) include/lcd_ast.h
$(CXX) $(CXXFLAGS) -c -o $@ $(filter-out %.h,$^)
scope.o: ast/scope.cpp include/lcd_ast.h
$(CXX) $(CXXFLAGS) -c -o $@ $(filter-out %.h,$^)
lcd_ast.o: ast/lcd_ast.cpp include/lcd_ast.h
$(CXX) $(CXXFLAGS) -c -o $@ $(filter-out %.h,$^)
include/lcd_idl.h: parser/lcd_idl.peg
parser/vembyr-1.1/peg.py --h $^ > $@
parser/lcd_idl.cpp: parser/lcd_idl.peg
parser/vembyr-1.1/peg.py --cpp $^ > $@
clean:
rm parser/lcd_idl.cpp parser/lcd_idl.h lcd_ast.h.gch compiler *.o
-rm -f $(objects) $(bin) $(idl) lcd_ast.h.gch
test: compiler
test: $(bin)
./test/test.py
#include "../include/lcd_ast.h"
#include "lcd_ast.h"
#include <stdio.h>
Typedef::Typedef(const char* alias, Type* type)
{
......@@ -8,9 +9,15 @@ Typedef::Typedef(const char* alias, Type* type)
void Typedef::accept(ASTVisitor* worker)
{
printf("in typedef accept\n");
worker->visit(this);
}
const char* Typedef::alias()
{
return this->alias_;
}
IntegerType::IntegerType(const char* type, bool un, int size)
{
this->type_ = type;
......@@ -20,9 +27,20 @@ IntegerType::IntegerType(const char* type, bool un, int size)
void IntegerType::accept(ASTVisitor* worker)
{
printf("in integertype accept\n");
worker->visit(this);
}
const char* IntegerType::type()
{
return this->type_;
}
bool IntegerType::unsigned_huh()
{
return unsigned_;
}
PointerType::PointerType(Type* type)
{
this->type_ = type;
......@@ -30,9 +48,15 @@ PointerType::PointerType(Type* type)
void PointerType::accept(ASTVisitor* worker)
{
printf("pointer type accept\n");
worker->visit(this);
}
Type* PointerType::type()
{
return this->type_;
}
ProjectionField::ProjectionField(bool in, bool out, bool alloc, bool bind, Type* field_type, const char* field_name)
{
this->in_ = in; this->out_ = out; this->alloc_ = alloc; this->bind_ = bind; this->field_type_ = field_type; this->field_name_ = field_name;
......@@ -70,9 +94,20 @@ ProjectionType::ProjectionType(const char* id, const char* real_type, std::vecto
void ProjectionType::accept(ASTVisitor* worker)
{
printf("in projectype accept\n");
worker->visit(this);
}
const char* ProjectionType::id()
{
return this->id_;
}
const char* ProjectionType::real_type()
{
return this->real_type_;
}
Parameter::Parameter(Type* type, const char* name)
{
this->type_ = type;
......@@ -84,6 +119,16 @@ void Parameter::accept(ASTVisitor* worker)
worker->visit(this);
}
Type* Parameter::type()
{
return this->type_;
}
const char* Parameter::name()
{
return this->name_;
}
Rpc::Rpc(Type* return_type, const char* name, std::vector<Parameter* >* parameters)
{
this->ret_type_ = return_type;
......@@ -103,6 +148,7 @@ Type* Rpc::return_type()
void Rpc::accept(ASTVisitor* worker)
{
printf("in rpc accpet\n");
worker->visit(this);
}
......@@ -120,5 +166,12 @@ File::File(const char* verbatim, FileScope* fs, std::vector<Rpc* >* rpc_definiti
void File::accept(ASTVisitor* worker)
{
printf("in accept and trying to print size %lu\n", this->rpc_defs_->size());
printf("in accept\n");
worker->visit(this);
}
std::vector<Rpc*>* File::rpc_defs()
{
return this->rpc_defs_;
}
#include "../include/lcd_ast.h"
#include "lcd_ast.h"
#include <stdio.h>
RootScope* RootScope::instance_ = 0;
RootScope::RootScope()
{
// init builtin int types
this->types_ = new std::map<const char*, Type*>();
this->types_ = new std::map<std::string, Type*>();
// instert for each builtin in type, add size to type if not done alreayd
this->types_->insert( std::pair<const char*,Type*>("char"
, new IntegerType("char", false, sizeof("char"))));
this->types_->insert( std::pair<const char*,Type*>("unsigned char"
, new IntegerType("unsigned char", true, sizeof("char"))));
this->types_->insert( std::pair<const char*,Type*>("short"
, new IntegerType("short", false, sizeof("short"))));
this->types_->insert( std::pair<const char*,Type*>("unsigned short"
, new IntegerType("unsigned short", true, sizeof("short"))));
this->types_->insert( std::pair<const char*,Type*>("int"
, new IntegerType("int", false, sizeof("int"))));
this->types_->insert( std::pair<const char*,Type*>("unsigned int"
, new IntegerType("unsigned int", true, sizeof("int"))));
this->types_->insert( std::pair<const char*,Type*>("long"
, new IntegerType("long", false, sizeof("long"))));
this->types_->insert( std::pair<const char*,Type*>("unsigned long"
, new IntegerType("unsigned long", true, sizeof("long"))));
this->types_->insert( std::pair<const char*,Type*>("long long"
, new IntegerType("long long", false, sizeof("long long"))));
this->types_->insert( std::pair<const char*,Type*>("unsigned long long"
, new IntegerType("unsigned long long", true, sizeof("long long"))));
this->types_->insert( std::pair<const char*,Type*>("capability"
, new IntegerType("capability_t", false, sizeof("int"))));
this->types_->insert( std::pair<std::string,Type*>("char"
, new IntegerType("char", false, sizeof(char))));
this->types_->insert( std::pair<std::string,Type*>("unsigned char"
, new IntegerType("unsigned char", true, sizeof(char))));
this->types_->insert( std::pair<std::string,Type*>("short"
, new IntegerType("short", false, sizeof(short))));
this->types_->insert( std::pair<std::string,Type*>("unsigned short"
, new IntegerType("unsigned short", true, sizeof(short))));
this->types_->insert( std::pair<std::string,Type*>("int"
, new IntegerType("int", false, sizeof(int))));
this->types_->insert( std::pair<std::string,Type*>("unsigned int"
, new IntegerType("unsigned int", true, sizeof(int))));
this->types_->insert( std::pair<std::string,Type*>("long"
, new IntegerType("long", false, sizeof(long))));
this->types_->insert( std::pair<std::string,Type*>("unsigned long"
, new IntegerType("unsigned long", true, sizeof(long))));
this->types_->insert( std::pair<std::string,Type*>("long long"
, new IntegerType("long long", false, sizeof(long long))));
this->types_->insert( std::pair<std::string,Type*>("unsigned long long"
, new IntegerType("unsigned long long", true, sizeof(long long))));
this->types_->insert( std::pair<std::string,Type*>("capability"
, new IntegerType("capability_t", false, sizeof(int))));
}
RootScope* RootScope::instance()
......@@ -41,18 +42,23 @@ RootScope* RootScope::instance()
Type * RootScope::lookup_symbol(const char * sym, int* err)
{
if(types_->find(sym) == types_->end())
std::string temp = sym;
if(this->types_->find(temp) == this->types_->end())
{
// error
// printf("looking up %s\n", sym);
// printf("is empty? %d\n", this->types_->size());
*err = 0;
return 0;
}
else
return (*types_)[sym];
return (*(this->types_))[temp];
}
int RootScope::insert_symbol(const char* sym, Type * value)
{
std::pair<std::map<const char*,Type*>::iterator,bool> ret;
ret = types_->insert(std::pair<const char*, Type*>(sym, value));
std::string temp = sym;
std::pair<std::map<std::string,Type*>::iterator,bool> ret;
ret = types_->insert(std::pair<std::string, Type*>(temp, value));
return ret.second;
}
......@@ -60,21 +66,23 @@ int RootScope::insert_symbol(const char* sym, Type * value)
// file scope
Type* FileScope::lookup_symbol(const char* sym, int* err)
{
std::string temp = sym;
// lookup here or root first?
if(types_->find(sym) == types_->end())
if(types_->find(temp) == types_->end())
{
// error
}
else
return (*types_)[sym];
return (*types_)[temp];
}
int FileScope::insert_symbol(const char* sym, Type* value)
{
std::string temp = sym;
// redefinition of something at root scope?
std::pair<std::map<const char*,Type*>::iterator, bool> ret;
ret = types_->insert(std::pair<const char*,Type*>(sym, value));
std::pair<std::map<std::string,Type*>::iterator, bool> ret;
ret = types_->insert(std::pair<std::string,Type*>(temp, value));
return ret.second;
......@@ -83,6 +91,6 @@ int FileScope::insert_symbol(const char* sym, Type* value)
FileScope::FileScope(RootScope* root)
{
this->root_ = root;
this->types_ = new std::map<const char*, Type*>();
this->types_ = new std::map<std::string, Type*>();
}
#include "visitor.h"
int generate_header_file(Interface * i, FILE * f_out)
{
// we have an interface, one per file
// need to write this out to a header file
// what includes?
// for each message in the interface write out to the file
// a function definition for each message
std::vector<Message*> * functions = i->getMessages();
for(std::vector<Message*>::iterator it = functions->begin(); it != functions->end(); it ++)
{
char * str_out;
Message * m = *it;
std::vector<Argument*> * args = m->getArguments();
char * args_str;
if(args->size() == 0)
{
args_str = (char *) malloc(sizeof(char));
args_str[0] = ' ';
}
else
char * args_str = construct_args_str(args);
int err = sprintf(str_out,"%s %s(%s);\n", "void", m->getName(), args_str);
if(err < 0)
{
printf("error using sprintf\n");
return -1;
}
fputs(str_out, f_out);
}
// all messages return void?
// need to match up each Type with an actual C type, builtin type
// or a typedef etc, support this later
fclose(f_out);
return 0;
}
char * construct_args_str(std::vector<Argument*> * args)
{
if(args->size() == 0)
printf("args size is zero\n");
int str_len = 0;
std::vector<char *> format_args = std::vector<char *>();
for(std::vector<Argument*>::iterator it = args->begin(); it != args->end(); it ++)
{
printf("in for loop\n");
char * str_arg;
Argument * a = *it;
if(a->isDynamic())
{
char * type = a->getType()->getStr();
char * name = a->getName();
char * size = a->getSize();
int len = strlen(type) + strlen(size) + strlen(name);
str_arg = (char *) malloc(sizeof(char)*(4+len));
int err = sprintf(str_arg, "%s %s[%s]", type, name, size);
if(err < 0)
printf("error using sprintf\n");
}
else
{
char * type = a->getType()->getStr();
printf("type is: %s\n", type);
char * name = a->getName();
int len = strlen(type) + strlen(name);
str_arg = (char *) malloc(sizeof(char)*(2+len));
int err = sprintf(str_arg, "%s %s", type, name);
printf("%s\n", str_arg);
if(err < 0)
printf("error using sprintf\n");
}
format_args.push_back(str_arg);
str_len = str_len + strlen(str_arg);
}
char * total_args = (char *) malloc(sizeof(char)*(str_len+1) + sizeof(char)* (arg_count -1));
char * first = format_args.front();
printf("got here\n");
strcpy(total_args, first);
format_args.erase(format_args.begin());
char * comma = (char *)malloc(sizeof(char)*2);
comma[0] = ',';
comma[1] = '\0';
for(std::vector<char*>::iterator it2 = format_args.begin(); it2 != format_args.end(); it2 ++)
{
// need to add commas
strcat(total_args, comma);
strcat(total_args, *it2);
}
return total_args;
}
int generate_stub_file(Interface * i, FILE * f_out)
{
return 0;
}
#include "../include/gen_visitor.h"
#include "gen_visitor.h"
#include <stdio.h>
HeaderVisitor::HeaderVisitor(FILE* out)
{
this->out_file_ = out;
this->out_f_ = out;
}
void HeaderVisitor::visit(File* f)
......@@ -12,7 +13,8 @@ void HeaderVisitor::visit(File* f)
// need to go through all typedef and print out
// a c typedef in file scope
for(std::vector<Rpc*>::iterator it = f->rpc_defs_->begin(); it != rpc_defs.end(); it++)
printf("in file\n");
for(std::vector<Rpc*>::iterator it = f->rpc_defs()->begin(); it != f->rpc_defs()->end(); it++)
{
Rpc* r = (Rpc*) *it;
r->accept(this);
......@@ -22,16 +24,19 @@ void HeaderVisitor::visit(File* f)
void HeaderVisitor::visit(Rpc* r)
{
Type* rt = r->ret_type;
printf("here\n");
Type* rt = r->return_type();
printf("here in hv hisit rpc\n");
printf("%d\n", rt->num());
rt->accept(this); // this seems unnecessary in this case
char* name = r->name_;
const char* name = r->name();
fprintf(this->out_f_, " %s ", name);
for(std::vector<Parameter*>::iterator it = r->params->begin(); it != r->params->end(); it++)
for(std::vector<Parameter*>::iterator it = r->parameters()->begin(); it != r->parameters()->end(); it++)
{
Paramter* p = (Parameter*) *it;
Parameter* p = (Parameter*) *it;
p->accept(this);
if((it+1) != r->params->end())
if((it+1) != r->parameters()->end())
fprintf(this->out_f_, ", ");
}
fprintf(this->out_f_, ");");
......@@ -39,14 +44,14 @@ void HeaderVisitor::visit(Rpc* r)
void HeaderVisitor::visit(Parameter* p)
{
p->type_->accept(this);
p->type()->accept(this);
// print p->name_
fprintf(this->out_f_, "%s", p->name_);
fprintf(this->out_f_, "%s", p->name());
}
void HeaderVisitor::visit(ProjectionType* p)
{
fprintf(this->out_f_, "%s", p->real_type_);
fprintf(this->out_f_, "%s", p->real_type());
}
void HeaderVisitor::visit(ProjectionField* pf)
......@@ -56,9 +61,11 @@ void HeaderVisitor::visit(ProjectionField* pf)
void HeaderVisitor::visit(IntegerType* it)
{
if(it->unsigned_)
if(it->unsigned_huh())
fprintf(this->out_f_, "unsigned ");
fprintf(this->out_f_, "%s", it->type());
/*
switch (it->type_) {
case kChar:
fprintf(this->out_f_, "char");
......@@ -81,11 +88,12 @@ void HeaderVisitor::visit(IntegerType* it)
default:
//error
}
*/
}
void HeaderVisitor::visit(PointerType* pt)
{
pt->type_->accept(this);
pt->type()->accept(this);
fprintf(this->out_f_, "* ");
}
......@@ -93,5 +101,5 @@ void HeaderVisitor::visit(Typedef* td)
{
// print out their type so they arent confused
// print td->alias;
fprintf(this->out_f_, "%s", td->alias);
fprintf(this->out_f_, "%s", td->alias());
}
#include "../include/gen_visitor.h"
#include "gen_visitor.h"
void SourceVisitor::visit(File* f)
{
......
File <-
Interface <- INTERFACE Identifier Description?
OPENC Type* Message+ CLOSEC SEMI SPACING
Message <- MESSAGE Identifier OPEN Arguments CLOSE SEMI SPACING
Arguments <- ArgStart* ArgLast?
ArgStart <- (SimpleArg / DynamicArg) COMMA
ArgLast <- (SimpleArg / DynamicArg)
SimpleArg <- Type Identifier
DynamicArg <- Type Identifier OPENS Identifier CLOSES
Type <- 'bool' / 'int32' / 'char'
Identifier <- IdentStart IdentCont* Spacing
IdentStart <- [a-zA-Z_]
IdentCont <- IdentStart / [0-9]
// reserved words
MESSAGE <- 'message' Spacing
INTERFACE <- 'interface' Spacing
SEMI <- ';'
OPENC <- '{'
CLOSEC <- '}'
OPENS <- '['
CLOSES <- ']'
OPEN <- '('
CLOSE <- ')'
COMMA <- ','
Spacing <- Space*
Space <- ' ' / '\t' / EndOfLine
Comment <- ('/*' .* '*/'
/ '//' (!EndOfLine .)* EndOfLine)
EndOfLine <- '\r\n' / '\n' / '\r'
#include "header_generator.h"
void HeaderGeneratorVisitor::visit(File *file)
{
// maybe i should change name again
// print out verbatim section
// call accept on all rpc definitions
// what about messages again?
// what to do about symbol table
}
void HeaderGeneratorVisitor::visit(Message *message)
{
// what is a message used for agian?
}
void HeaderGeneratorVisitor::visit(MessageField *message_field)
{
// what is a message used for again?
}
void HeaderGeneratorVisitor::visit(Projection *projection)
{
// don't need to do anything? only relevant
// in c file generation
}
void HeaderGeneratorVisitor::visit(ProjectionField *proj_field)
{
// do we need to do anything for header generation?
// i believe this is only needed when generating
// c files
}
void HeaderGeneratorVisitor::visit(Rpc *rpc)
{
// need to call accept on the return type
// need to print the name and paren
// need to call accept on each of the parameters
}
void HeaderGeneratorVisitor::visit(Parameter *param)
{
// need to call accept on the type and print the
// name
}
void HeaderGeneratorVisitor::visit(Typedef *typedef)
{
// do we need one for teypdefs? if we are replacing
// the use of the typedef in the file, with the real type
// we don't need to print a c typedef at the top, especially if there is one in another file
// may not need a visit for typedef? talk to anton
}
void HeaderGeneratorVisitor::visit(ProjectionType *proj_type)
{
// just need to print the underlying type
}
void HeaderGeneratorVisitor::visit(PrimitiveType *prim_type)
{
// just need to print the entire type....
}
void HeaderGeneratorVisitor::visit(UnresolvedType *unresolved_type)
{
// need to lookup type in symbol table
}
#include "ast.h"
#include "flounder_parser.h"
#include "stub-generator.h"
#include "header-generator.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
int main(int argc, char ** argv)
{
if(argc != 4)
{
printf("Command line must be of form: -option in_file out_file\n");
exit(0);
}
try
{
char * option = argv[1];
char * in_file = argv[2];
char * out_file = argv[3];
if(strstr(option,"-header"))
{
FILE * out;
Interface * tree = (Interface *) Parser::parse(std::string(in_file));
printf("we have a tree\n");
out = fopen(out_file, "w");
printf("we have opened a file\n");
generate_header_file(tree, out);
}
else if(strstr(option,"-stub"))
{
FILE * out;
Interface * tree = (Interface *) Parser::parse(std::string(in_file));
out = fopen(out_file, "w");
generate_stub_file(tree, out);
}
else
printf("not a valid option: %s\n", option);
exit(0);
}
catch (const Parser::ParseException &e)
{
printf("caught an exception\n");
std::cout << e.getReason();
}
}
#ifndef LCD_HEADER_GENERATOR_H_
#define LCD_HEADER_GENERATOR_H_
#include "lcd_ast.h"
#include <stdio.h>
int GenerateHeader(Scope* tree, FILE* out_file);
#endif // LCD_HEADER_GENERATOR_H_
#ifndef GEN_VISITOR
#define GEN_VISITOR
#include "visitor.h"
#include "lcd_ast.h"
#include <stdio.h>
class GenVisitor : public ASTVisitor
{
FILE* out_f_;
//FILE* out_f_;
public:
virtual void visit(File *f) =0;
virtual void visit(Rpc *rpc) =0;
......@@ -19,7 +20,7 @@ class GenVisitor : public ASTVisitor
class HeaderVisitor : public GenVisitor
{
//FILE* out_f_;
FILE* out_f_;
public:
HeaderVisitor(FILE* f);
virtual void visit(File *f);
......
#ifndef LCD_HEADER_GENERATOR_H_
#define LCD_HEADER_GENERATOR_H_
#include "lcd_ast.h"
#include "visitor.h"
#include <stdio.h>
class HeaderGeneratorVisitor : public ASTVisitor
{