| 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 |