1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
#include "stdafx.h"
#include "Parser.h"
#include "TemplateList.h"
#include "Exception.h"
#include "Engine.h"
#include "Array.h"
#include "Compiler/Syntax/Rule.h"
#include "Compiler/Syntax/Parser.h"
#include "Compiler/Package.h"
namespace storm {
using syntax::Rule;
using syntax::ParserBase;
using syntax::ParserBackend;
Type *createParser(Str *name, ValueArray *params) {
if (params->count() != 1)
return null;
Value param = params->at(0);
if (param.ref)
return null;
if (Rule *r = as<Rule>(param.type))
return new (params) ParserType(name, r);
else
return null;
}
ParserType *parserType(Rule *rule) {
Engine &e = rule->engine;
TemplateList *l = e.cppTemplate(syntax::ParserId);
NameSet *to = l->addTo();
assert(to, L"Too early to use 'parserType'");
ParserType *found = as<ParserType>(to->find(S("Parser"), Value(rule), Scope()));
if (!found)
throw new (rule) InternalError(S("Can not find the parser type!"));
return found;
}
namespace syntax {
void CODECALL createParser(void *mem, ParserBackend *backend) {
ParserBase *p = new (Place(mem)) ParserBase(backend);
runtime::setVTable(p);
}
static void CODECALL createDefParser(void *mem) {
createParser(mem, null);
}
}
static void CODECALL createParserPkg(void *mem, Package *p, ParserBackend *backend) {
syntax::createParser(mem, backend);
((ParserBase *)mem)->addSyntax(p);
}
static void CODECALL createDefParserPkg(void *mem, Package *p) {
createParserPkg(mem, p, null);
}
static void CODECALL createParserArr(void *mem, Array<Package *> *p, ParserBackend *backend) {
syntax::createParser(mem, backend);
((ParserBase *)mem)->addSyntax(p);
}
static void CODECALL createDefParserArr(void *mem, Array<Package *> *p) {
createParserArr(mem, p, null);
}
static TObject *CODECALL parserTree(ParserBase *me) {
return me->tree();
}
ParserType::ParserType(Str *name, Rule *rule)
: Type(name, new (this) Array<Value>(1, Value(rule)), typeClass),
root(rule) {
setSuper(syntax::ParserBase::stormType(engine));
}
Bool ParserType::loadAll() {
Engine &e = engine;
Value t = thisPtr(this);
Value pkg = thisPtr(Package::stormType(e));
Value arr = wrapArray(pkg);
Value rule = thisPtr(root);
Value backend = thisPtr(ParserBackend::stormType(e));
add(nativeFunction(e, Value(), Type::CTOR, valList(e, 1, t), address(&syntax::createDefParser)));
add(nativeFunction(e, Value(), Type::CTOR, valList(e, 2, t, backend), address(&syntax::createParser)));
add(nativeFunction(e, Value(), Type::CTOR, valList(e, 2, t, pkg), address(&createDefParserPkg)));
add(nativeFunction(e, Value(), Type::CTOR, valList(e, 3, t, pkg, backend), address(&createParserPkg)));
add(nativeFunction(e, Value(), Type::CTOR, valList(e, 2, t, arr), address(&createDefParserArr)));
add(nativeFunction(e, Value(), Type::CTOR, valList(e, 3, t, arr, backend), address(&createParserArr)));
add(nativeFunction(e, rule, S("tree"), valList(e, 1, t), address(&parserTree)));
return Type::loadAll();
}
}
|