OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library immic.parser; | |
6 | |
7 import 'package:petitparser/petitparser.dart'; | |
8 import 'grammar.dart'; | |
9 import 'primitives.dart' as primitives; | |
10 import 'struct_layout.dart'; | |
11 import 'package:path/path.dart' as p; | |
12 | |
13 Unit parseUnit(String input) { | |
14 Parser parser = new GrammarParser(new _ImmiParserDefinition()); | |
15 return parser.parse(input).value; | |
16 } | |
17 | |
18 abstract class Visitor { | |
19 visitUnit(Unit unit); | |
20 visitImport(Import import); | |
21 visitStruct(Struct struct); | |
22 visitUnion(Union union); | |
23 visitMethod(Method method); | |
24 visitFormal(Formal formal); | |
25 } | |
26 | |
27 enum InputKind { | |
28 PRIMITIVES, | |
29 STRUCT | |
30 } | |
31 | |
32 enum OutputKind { | |
33 PRIMITIVE, | |
34 STRUCT | |
35 } | |
36 | |
37 abstract class Node { | |
38 accept(Visitor visitor); | |
39 } | |
40 | |
41 class Unit extends Node { | |
42 final List<Import> imports; | |
43 final List<Struct> structs; | |
44 Unit(this.imports, this.structs); | |
45 accept(Visitor visitor) => visitor.visitUnit(this); | |
46 } | |
47 | |
48 class Import extends Node { | |
49 static const String packagePrefix = 'package:'; | |
50 String import; | |
51 String package; | |
52 String path; | |
53 | |
54 Import(List<String> importData) { | |
55 import = importData.join(); | |
56 if (import.startsWith(packagePrefix)) { | |
57 package = p.split(import)[0].split(':')[1]; | |
58 path = import.substring(packagePrefix.length + package.length + 1); | |
59 } else { | |
60 path = import; | |
61 } | |
62 } | |
63 | |
64 String get extension => p.extension(path); | |
65 | |
66 accept(Visitor visitor) => visitor.visitImport(this); | |
67 } | |
68 | |
69 class Struct extends Node { | |
70 final String name; | |
71 final List<Formal> slots; | |
72 final List<Union> unions; | |
73 final List<Method> methods; | |
74 Struct(this.name, this.slots, this.unions, this.methods); | |
75 | |
76 // Set by the resolver. | |
77 StructLayout layout; | |
78 | |
79 accept(Visitor visitor) => visitor.visitStruct(this); | |
80 } | |
81 | |
82 class Union extends Node { | |
83 final List<Formal> slots; | |
84 final Formal tag; | |
85 Union(this.slots) : tag = new Formal(new SimpleType("uint16", false), "tag"); | |
86 | |
87 // Set by the resolver. | |
88 Struct struct; | |
89 | |
90 accept(Visitor visitor) => visitor.visitUnion(this); | |
91 } | |
92 | |
93 class Formal extends Node { | |
94 final Type type; | |
95 final String name; | |
96 Formal(this.type, this.name); | |
97 | |
98 accept(Visitor visitor) => visitor.visitFormal(this); | |
99 } | |
100 | |
101 class Method extends Node { | |
102 final String name; | |
103 final List<Formal> arguments; | |
104 final Type returnType; | |
105 Method(this.name, this.arguments, this.returnType); | |
106 | |
107 // Set by the resolver. | |
108 OutputKind outputKind; | |
109 | |
110 InputKind inputKind; | |
111 StructLayout inputPrimitiveStructLayout; | |
112 | |
113 accept(Visitor visitor) => visitor.visitMethod(this); | |
114 } | |
115 | |
116 abstract class Type { | |
117 bool get isPointer => false; | |
118 bool get isList => false; | |
119 bool get isString => false; | |
120 bool get isNode => false; | |
121 | |
122 bool get isPrimitive => primitiveType != null; | |
123 | |
124 bool get isVoid => primitiveType == primitives.PrimitiveType.VOID; | |
125 bool get isBool => primitiveType == primitives.PrimitiveType.BOOL; | |
126 | |
127 // TODO(kasperl): Get rid of this. | |
128 String get identifier; | |
129 | |
130 // Set by the resolver. | |
131 Node resolved; | |
132 primitives.PrimitiveType primitiveType; | |
133 } | |
134 | |
135 class StringType extends Type { | |
136 final String identifier = "String"; | |
137 | |
138 int get hashCode { | |
139 int hash = identifier.hashCode; | |
140 return hash; | |
141 } | |
142 | |
143 bool operator==(Object other) { | |
144 return other is StringType; | |
145 } | |
146 | |
147 bool get isString => true; | |
148 } | |
149 | |
150 class NodeType extends Type { | |
151 final String identifier = "node"; | |
152 | |
153 int get hashCode { | |
154 int hash = identifier.hashCode; | |
155 return hash; | |
156 } | |
157 | |
158 bool operator==(Object other) { | |
159 return other is NodeType; | |
160 } | |
161 | |
162 bool get isNode => true; | |
163 } | |
164 | |
165 class SimpleType extends Type { | |
166 final String identifier; | |
167 final bool isPointer; | |
168 SimpleType(this.identifier, this.isPointer); | |
169 | |
170 int get hashCode { | |
171 int hash = identifier.hashCode; | |
172 if (isPointer) { | |
173 hash = hash ^ ((hash >> 16) | (hash << 16)); | |
174 } | |
175 return hash; | |
176 } | |
177 | |
178 bool operator==(Object other) { | |
179 return other is SimpleType | |
180 && identifier == other.identifier | |
181 && isPointer == other.isPointer; | |
182 } | |
183 } | |
184 | |
185 class ListType extends Type { | |
186 final SimpleType elementType; | |
187 ListType(this.elementType); | |
188 | |
189 int get hashCode { | |
190 int hash = elementType.hashCode; | |
191 return ((hash >> 16) | (hash << 16)); | |
192 } | |
193 | |
194 bool operator==(Object other) { | |
195 return other is ListType && elementType == other.elementType; | |
196 } | |
197 | |
198 bool get isList => true; | |
199 | |
200 String get identifier => elementType.identifier; | |
201 } | |
202 | |
203 // -------------------------------------------------------------- | |
204 | |
205 class _ImmiParserDefinition extends ImmiGrammarDefinition { | |
206 final StringType string = new StringType(); | |
207 final NodeType node = new NodeType(); | |
208 unit() => super.unit() | |
209 .map((each) => new Unit( | |
210 each[0].toList(), | |
211 each[1].where((e) => e is Struct).toList())); | |
212 import() => super.import() | |
213 .map((each) => new Import(each[1][1])); | |
214 struct() => super.struct() | |
215 .map((each) => new Struct(each[1], | |
216 each[3].where((e) => e is Formal).toList(), | |
217 each[3].where((e) => e is Union).toList(), | |
218 each[3].where((e) => e is Method).toList())); | |
219 method() => super.method() | |
220 .map((each) => new Method(each[1], each[3], each[0])); | |
221 simpleType() => super.simpleType() | |
222 .map((each) => new SimpleType(each[0], each[1])); | |
223 stringType() => super.stringType().map((each) => string); | |
224 nodeType() => super.nodeType().map((each) => node); | |
225 listType() => super.listType() | |
226 .map((each) => new ListType(each[2])); | |
227 union() => super.union() | |
228 .map((each) => new Union(each[2])); | |
229 slot() => super.slot() | |
230 .map((each) => each[0]); | |
231 formal() => super.formal() | |
232 .map((each) => new Formal(each[0], each[1])); | |
233 identifier() => super.identifier() | |
234 .flatten().map((each) => each.trim()); | |
235 } | |
OLD | NEW |