File: Parser.cpp

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,004 kB
  • sloc: ansic: 261,462; cpp: 140,405; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (100 lines) | stat: -rw-r--r-- 3,043 bytes parent folder | download | duplicates (3)
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();
	}

}