summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--lib/sitecing_enflesher.ll1
1 files changed, 0 insertions, 1 deletions
diff --git a/lib/sitecing_enflesher.ll b/lib/sitecing_enflesher.ll
index bb667be..f833af2 100644
--- a/lib/sitecing_enflesher.ll
+++ b/lib/sitecing_enflesher.ll
@@ -1,260 +1,259 @@
%{
#include <iostream>
#include <fstream>
#include <cassert>
#include <stdexcept>
using namespace std;
#include "sitecing/sitecing_exception.h"
using namespace sitecing;
#define sitecing_enflesher_flexlexer_once
#include "sitecing/sitecing_enflesher.h"
#include "sitecing/sitecing_parser.h"
#undef yyFlexLexer
#define yyFlexLexer sitecing_enflesherFlexLexer
%}
%option 8bit c++ verbose noyywrap yyclass="sitecing_enflesher" yylineno prefix="sitecing_enflesher" stack debug
ID [A-Za-z_][A-Za-z0-9_]*
%%
^\%\%\#[^\n]+\n {
string line = yytext;
line.erase(0,3);
line.erase(line.length()-1);
outs_open(parser.output_basename+line);
anchor();
anchoraged = true;
}
^\%\%[^\n]+\n {
string line = yytext;
line.erase(0,2);
line.erase(line.length()-1);
outs_open(parser.output_basename+line);
anchoraged = false;
}
\<\%component_basename\%\> outs << parser.component_basename; anchor_time = true;
\<\%impl\%\> outs << parser.impl; anchor_time = true;
\<\%member_functions:impl\%\> {
for(sitecing_parser::member_functions_t::const_iterator i=parser.member_functions.begin();i!=parser.member_functions.end();i++) {
outs << i->type << " " << parser.class_name << "::";
if(i->name.empty()) {
outs << parser.class_name << "()";
bool first = true;
for(sitecing_parser::member_variables_t::iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) {
if(i->initializer.empty())
continue;
if(first) {
outs << ":";
first=false;
}else{
outs << ",";
}
if(i->bComponent) {
outs << i->name << "(NULL)";
}else {
outs << i->name << "(" << i->initializer << ")";
}
}
}else if(i->name == "~")
outs << "~" << parser.class_name << "()";
else
outs << i->name << i->args;
outs << "{\n" << i->body << "\n}\n";
}
anchor_time = true;
}
\<\%class_name\%\> outs << parser.class_name; anchor_time = true;
\<\%baseclass_header\%\> outs << parser.base_header; anchor_time = true;
\<\%decl\%\> outs << parser.decl; anchor_time = true;
\<\%baseclass_name\%\> outs << parser.base_class; anchor_time = true;
\<\%member_variables:decl\%\> {
for(sitecing_parser::member_variables_t::iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) {
if(i->bComponent) {
if(i->type.empty()) {
i->type = parser.factory.get_classname(i->initializer);
}
if(i->bTypeOnly) {
outs << "typedef " << i->type << " " << i->name << ";\n";
}else{
outs << "typedef " << i->type << " __type_" << i->name << ";\nsitecing::so_component __soc_" << i->name << ";\n__type_" << i->name << " *" << i->name << ";\n";
}
}else{
outs << i->type << " " << i->name << ";\n";
}
}
anchor_time = true;
}
\<\%member_functions:decl\%\> {
for(sitecing_parser::member_functions_t::const_iterator i=parser.member_functions.begin();i!=parser.member_functions.end();i++) {
(i->name.empty()?outs:outs << "virtual ")
<< i->type << " ";
if(i->name.empty()) {
outs << parser.class_name << "()";
}else if(i->name == "~")
outs << "~" << parser.class_name << "()";
else
outs << i->name << i->args;
outs << ";\n";
}
anchor_time = true;
}
\<\%imports:list\%\> {
for(sitecing_parser::member_variables_t::const_iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) {
if(i->bComponent)
outs << i->initializer << endl;
}
anchor_time = true;
}
\<\%imports:includes\%\> {
for(sitecing_parser::member_variables_t::iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) {
if(i->bComponent)
outs << "\n#include \"" << i->initializer << ".h\"\n";
}
anchor_time = true;
}
\<\%imports:import\%\> {
for(sitecing_parser::member_variables_t::iterator i=parser.member_variables.begin();i!=parser.member_variables.end();i++) {
if(!i->bComponent)
continue;
if(i->bTypeOnly)
continue;
outs << "__soc_" << i->name << "=__SCIF->ss->fetch(\"" << i->initializer << "\",__SCIF); " << i->name << "=static_cast<__type_" << i->name << "*>(__soc_" << i->name << ".ac->__the_most_derived_this());\n";
}
anchor_time = true;
}
\<\%base_component\%\> {
// TODO:
anchor_time = true;
}
\<\%ancestors:includes\%\> {
for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) {
outs << "#include \"" << i->path << ".h\"\n";
}
anchor_time = true;
}
\<\%ancestors:component_list\%\> {
for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) {
outs << i->path << "\n";
}
anchor_time = true;
}
\<\%ancestors:base_clause_part\%\> {
for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) {
outs << ", virtual public " << parser.factory.get_classname(i->path);
}
}
\<\%ancestors:typedefs\%\> {
for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) {
outs << "typedef class " << parser.factory.get_classname(i->path) << " " << i->name << ";\n";
}
anchor_time = true;
}
\<\%ancestors:import\%\> {
for(sitecing_parser::ancestor_classes_t::const_iterator i=parser.ancestor_classes.begin();i!=parser.ancestor_classes.end();++i) {
outs << i->name << "::__do_imports();\n";
}
anchor_time = true;
}
\n {
if(anchor_time)
anchor();
ECHO;
}
. ECHO;
%%
void sitecing_enflesher::LexerOutput(const char *buf,int size) {
outs.write(buf,size);
}
void sitecing_enflesher::enflesh() {
ifstream ifs(parser.skeleton.c_str());
if(!ifs.good())
throw preprocessor_error(CODEPOINT,"failed to open skeleton file");
switch_streams(&ifs,NULL);
yylex();
outs_close();
}
void sitecing_enflesher::anchor() {
if(!anchoraged)
return;
outs << "\n#line " << lineno() << " \"" << parser.skeleton << "\"\n";
anchor_time = false;
}
void sitecing_enflesher::outs_close() {
if(!outs_filename.empty()) {
outs.flush();
outs.close();
outs.clear();
/*
* compare source and destination files.
*
* one can also keep a hash for the old one and compute one for the
* output while writing, but I'm not sure if it's any better. Surely a
* bit less accurate, unless we're going to compare it in case of
* difference, anyway.
*/
bool overwrite = false;
struct stat st_s, st_d;
string fn_s = outs_filename+".new";
string fn_d = outs_filename;
if(stat(fn_d.c_str(),&st_d)) {
overwrite = true;
}else{
if(stat(fn_s.c_str(),&st_s))
throw preprocessor_error(CODEPOINT,"failed to stat() supposedly created file");
if(st_s.st_size!=st_d.st_size) {
overwrite = true;
}else{
ifstream i_s(fn_s.c_str(),ios::in);
if(!i_s)
throw preprocessor_error(CODEPOINT,"failed to open supposedly created file");
ifstream i_d(fn_d.c_str(),ios::in);
if(!i_d)
throw preprocessor_error(CODEPOINT,"failed to open the old preprocessed source");
off_t remaining = st_s.st_size;
char t1[2048];
char t2[sizeof(t1)];
while(remaining) {
int rb = remaining;
if(rb>sizeof(t1))
rb = sizeof(t1);
if(i_s.read(t1,rb).gcount()!=rb)
throw preprocessor_error(CODEPOINT,"error reading just created file");
if(i_d.read(t2,rb).gcount()!=rb)
throw preprocessor_error(CODEPOINT,"error reading the old preprocessed source");
if(memcmp(t1,t2,rb)) {
overwrite = true;
break;
}
remaining -= rb;
}
}
}
if(overwrite) {
- cerr << "renaming '" << fn_s << "'" << endl;
if(rename(fn_s.c_str(),fn_d.c_str()))
throw preprocessor_error(CODEPOINT,"failed to rename() generated output");
}
}
outs_filename.erase();
}
void sitecing_enflesher::outs_open(const string& nfile) {
outs_close();
outs_filename = nfile;
outs.open((nfile+".new").c_str(),ios::trunc);
if(!outs.good())
throw preprocessor_error(CODEPOINT,"failed to write preprocessor output");
}
/*
* vim:set ft=lex:
*/