Index: tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart |
diff --git a/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart b/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart |
deleted file mode 100644 |
index e0252e71159c4d3735b67090c163717914e393a2..0000000000000000000000000000000000000000 |
--- a/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart |
+++ /dev/null |
@@ -1,885 +0,0 @@ |
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-// SExpressionUnstringifier implements the inverse operation to |
-// [SExpressionStringifier]. |
- |
-library sexpr_unstringifier; |
- |
-import 'package:compiler/src/constants/expressions.dart'; |
-import 'package:compiler/src/constants/values.dart'; |
-import 'package:compiler/src/dart_types.dart' as dart_types |
- show DartType; |
-import 'package:compiler/src/diagnostics/messages.dart' |
- show MessageKind; |
-import 'package:compiler/src/elements/elements.dart'; |
-import 'package:compiler/src/elements/modelx.dart' |
- show ErroneousElementX, TypeVariableElementX; |
-import 'package:compiler/src/tree/tree.dart' show LiteralDartString; |
-import 'package:compiler/src/universe/call_structure.dart' |
- show CallStructure; |
-import 'package:compiler/src/universe/selector.dart' |
- show Selector, SelectorKind; |
-import 'package:compiler/src/cps_ir/cps_ir_nodes.dart'; |
- |
-/// Used whenever a node constructed by [SExpressionUnstringifier] needs a |
-/// named entity. |
-class DummyEntity extends Entity { |
- final String name; |
- DummyEntity(this.name); |
-} |
- |
-/// Used whenever a node constructed by [SExpressionUnstringifier] needs a |
-/// local. |
-class DummyLocal extends DummyEntity implements Local { |
- DummyLocal(String name) : super(name); |
- |
- ExecutableElement get executableContext => null; |
-} |
- |
-// TODO(karlklose): we should remove all references to [ErroneousElement] from |
-// the CPS IR. Instead, the builder must construct appropriate terms for ASTs |
-// that could not be resolved correctly. Perhaps the IR should not rely on |
-// elements at all for naming. |
-/// Used whenever a node constructed by [SExpressionUnstringifier] requires |
-/// an [Element] or [FunctionElement]. Extends [ErroneousElementX] since there |
-/// is currently a large amount of overhead when extending the base abstract |
-/// classes, and erroneous elements conveniently also skip several assertion |
-/// checks in CPS IR nodes that are irrelevant to us. |
-class DummyElement extends ErroneousElementX |
- implements TypeVariableElement, FieldElement { |
- DummyElement(String name) |
- : super(MessageKind.GENERIC, {}, name, null); |
- |
- final dart_types.DartType bound = null; |
- final TypeDeclarationElement typeDeclaration = null; |
- |
- noSuchMethod(inv) => super.noSuchMethod(inv); |
-} |
- |
-/// Used whenever a node constructed by [SExpressionUnstringifier] requires |
-/// a named type. |
-class DummyNamedType extends dart_types.DartType { |
- final String name; |
- |
- final kind = null; |
- final element = null; |
- |
- DummyNamedType(this.name); |
- |
- subst(arguments, parameters) => null; |
- unalias(compiler) => null; |
- accept(visitor, argument) => null; |
- |
- String toString() => name; |
-} |
- |
-/// Represents a list of tokens, but is basically a partial view into a list |
-/// with appropriate convenience methods. |
-class Tokens { |
- final List<String> _list; |
- int _index; // Current index into the list. |
- |
- Tokens(List<String> this._list) : _index = 0; |
- |
- String get current => _list[_index]; |
- String get next => _list[_index + 1]; |
- |
- String read([String expected]) { |
- if (expected != null) { |
- if (current != expected) { |
- print('expected "$expected", found "$current"'); |
- int start = _index - 15; |
- String dotdotdot = '... '; |
- if (start < 0) { |
- start = 0; |
- dotdotdot = ''; |
- } |
- print('${dotdotdot}${_list.sublist(start, _index + 1).join(' ')}'); |
- assert(current == expected); |
- } |
- } |
- return _list[_index++]; |
- } |
- |
- /// Consumes the preamble to a new node, consisting of an opening parenthesis |
- /// and a tag. |
- void consumeStart([String tag]) { |
- read("("); |
- if (tag != null) { |
- read(tag); |
- } |
- } |
- |
- void consumeEnd() { |
- read(")"); |
- } |
- |
- bool get hasNext => _index < _list.length; |
- String toString() => _list.sublist(_index).toString(); |
-} |
- |
-/// Constructs a minimal in-memory representation of the IR represented |
-/// by the given string. Many fields are currently simply set to null. |
-class SExpressionUnstringifier { |
- |
- // Expressions |
- static const String BRANCH = "Branch"; |
- static const String CONCATENATE_STRINGS = "ConcatenateStrings"; |
- static const String DECLARE_FUNCTION = "DeclareFunction"; |
- static const String INVOKE_CONSTRUCTOR = "InvokeConstructor"; |
- static const String INVOKE_CONTINUATION = "InvokeContinuation"; |
- static const String INVOKE_STATIC = "InvokeStatic"; |
- static const String INVOKE_METHOD_DIRECTLY = "InvokeMethodDirectly"; |
- static const String INVOKE_METHOD = "InvokeMethod"; |
- static const String LET_PRIM = "LetPrim"; |
- static const String LET_CONT = "LetCont"; |
- static const String LET_MUTABLE = "LetMutable"; |
- static const String TYPE_CAST = "TypeCast"; |
- static const String GET_LAZY_STATIC = "GetLazyStatic"; |
- static const String UNREACHABLE = "Unreachable"; |
- |
- // Primitives |
- static const String CONSTANT = "Constant"; |
- static const String CREATE_FUNCTION = "CreateFunction"; |
- static const String GET_MUTABLE = "GetMutable"; |
- static const String SET_MUTABLE = "SetMutable"; |
- static const String LITERAL_LIST = "LiteralList"; |
- static const String LITERAL_MAP = "LiteralMap"; |
- static const String REIFY_TYPE_VAR = "ReifyTypeVar"; |
- static const String GET_STATIC = "GetStatic"; |
- static const String SET_STATIC = "SetStatic"; |
- static const String TYPE_TEST = "TypeTest"; |
- static const String APPLY_BUILTIN_OPERATOR = "ApplyBuiltinOperator"; |
- static const String GET_LENGTH = "GetLength"; |
- static const String GET_INDEX = "GetIndex"; |
- static const String SET_INDEX = "SetIndex"; |
- static const String GET_FIELD = "GetField"; |
- static const String SET_FIELD = "SetField"; |
- |
- // Other |
- static const String FUNCTION_DEFINITION = "FunctionDefinition"; |
- static const String IS_TRUE = "IsTrue"; |
- |
- // Constants |
- static const String BOOL = "Bool"; |
- static const String DOUBLE = "Double"; |
- static const String INT = "Int"; |
- static const String NULL = "Null"; |
- static const String STRING = "String"; |
- |
- final Map<String, Definition> name2variable = |
- <String, Definition>{ "return": new Continuation.retrn() }; |
- |
- // Operator names used for canonicalization. In theory, we could simply use |
- // Elements.isOperatorName() on the parsed tokens; however, comparisons are |
- // done using identical() for performance reasons, which are reliable only for |
- // compile-time literal strings. |
- static Set<String> OPERATORS = new Set<String>.from( |
- [ '~', '==', '[]', '*', '/', '%', '~/', '+', '<<', 'unary-' |
- , '>>', '>=', '>', '<=', '<', '&', '^', '|', '[]=', '-' |
- ]); |
- |
- // The tokens currently being parsed. |
- Tokens tokens; |
- |
- FunctionDefinition unstringify(String s) { |
- tokens = tokenize(s); |
- FunctionDefinition def = parseFunctionDefinition(); |
- assert(!tokens.hasNext); |
- return def; |
- } |
- |
- /// Returns a new named dummy selector with a roughly appropriate kind. |
- Selector dummySelector(String name, int argumentCount) { |
- SelectorKind kind; |
- if (name == "[]") { |
- kind = SelectorKind.INDEX; |
- } else if (Elements.isOperatorName(name)) { |
- kind = SelectorKind.OPERATOR; |
- } else { |
- kind = SelectorKind.CALL; |
- } |
- return new Selector(kind, new PublicName(name), |
- new CallStructure.unnamed(argumentCount)); |
- } |
- |
- /// Returns the tokens in s. Note that string literals are not necessarily |
- /// preserved; for instance, "(literalString)" is transformed to |
- /// " ( literalString ) ". |
- Tokens tokenize(String s) => |
- new Tokens( |
- s.replaceAll("(", " ( ") |
- .replaceAll(")", " ) ") |
- .replaceAll("{", " { ") |
- .replaceAll("}", " } ") |
- .replaceAll(new RegExp(r"[ \t\n]+"), " ") |
- .trim() |
- .split(" ") |
- .map(canonicalizeOperators) |
- .toList()); |
- |
- /// Canonicalizes strings containing operator names. |
- String canonicalizeOperators(String token) { |
- String opname = OPERATORS.lookup(token); |
- if (opname != null) { |
- return opname; |
- } |
- return token; |
- } |
- |
- Expression parseExpression() { |
- assert(tokens.current == "("); |
- |
- switch (tokens.next) { |
- case BRANCH: |
- return parseBranch(); |
- case CONCATENATE_STRINGS: |
- return parseConcatenateStrings(); |
- case DECLARE_FUNCTION: |
- return parseDeclareFunction(); |
- case INVOKE_CONSTRUCTOR: |
- return parseInvokeConstructor(); |
- case INVOKE_CONTINUATION: |
- return parseInvokeContinuation(); |
- case INVOKE_METHOD: |
- return parseInvokeMethod(); |
- case INVOKE_STATIC: |
- return parseInvokeStatic(); |
- case INVOKE_METHOD_DIRECTLY: |
- return parseInvokeMethodDirectly(); |
- case LET_PRIM: |
- return parseLetPrim(); |
- case LET_CONT: |
- return parseLetCont(); |
- case LET_MUTABLE: |
- return parseLetMutable(); |
- case TYPE_CAST: |
- return parseTypeCast(); |
- case GET_LAZY_STATIC: |
- return parseGetLazyStatic(); |
- case UNREACHABLE: |
- return parseUnreachable(); |
- default: |
- assert(false); |
- } |
- |
- return null; |
- } |
- |
- /// (prim1 prim2 ... primn) |
- List<Primitive> parsePrimitiveList() { |
- tokens.consumeStart(); |
- List<Primitive> prims = <Primitive>[]; |
- while (tokens.current != ")") { |
- Primitive prim = name2variable[tokens.read()]; |
- assert(prim != null); |
- prims.add(prim); |
- } |
- tokens.consumeEnd(); |
- return prims; |
- } |
- |
- /// (FunctionDefinition name (parameters) continuation body) |
- FunctionDefinition parseFunctionDefinition() { |
- tokens.consumeStart(FUNCTION_DEFINITION); |
- |
- // name |
- Element element = new DummyElement(""); |
- if (tokens.current != '(') { |
- // This is a named function. |
- element = new DummyElement(tokens.read()); |
- } |
- |
- // (this) or () |
- Definition thisParameter = null; |
- tokens.consumeStart(); |
- if (tokens.current != ')') { |
- String thisName = tokens.read(); |
- if (name2variable.containsKey(thisName)) { |
- thisParameter = name2variable[thisName]; |
- } else { |
- thisParameter = new Parameter(new DummyElement(thisName)); |
- name2variable[thisName] = thisParameter; |
- } |
- } |
- tokens.consumeEnd(); |
- |
- // (parameters) |
- List<Definition> parameters = <Definition>[]; |
- tokens.consumeStart(); |
- while (tokens.current != ")") { |
- String paramName = tokens.read(); |
- if (name2variable.containsKey(paramName)) { |
- parameters.add(name2variable[paramName]); |
- } else { |
- Parameter param = new Parameter(new DummyElement(paramName)); |
- name2variable[paramName] = param; |
- parameters.add(param); |
- } |
- } |
- tokens.consumeEnd(); |
- |
- // continuation |
- String contName = tokens.read("return"); |
- Continuation cont = name2variable[contName]; |
- assert(cont != null); |
- |
- // body |
- Expression body = parseExpression(); |
- |
- tokens.consumeEnd(); |
- return new FunctionDefinition(element, thisParameter, parameters, |
- new Body(body, cont), null, null); |
- } |
- |
- /// (IsTrue arg) |
- Condition parseCondition() { |
- // Handles IsTrue only for now. |
- tokens.consumeStart(IS_TRUE); |
- |
- Definition value = name2variable[tokens.read()]; |
- assert(value != null); |
- |
- tokens.consumeEnd(); |
- return new IsTrue(value); |
- } |
- |
- /// (Branch condition cont cont) |
- Branch parseBranch() { |
- tokens.consumeStart(BRANCH); |
- |
- Condition cond = parseCondition(); |
- Continuation trueCont = name2variable[tokens.read()]; |
- Continuation falseCont = name2variable[tokens.read()]; |
- assert(trueCont != null && falseCont != null); |
- |
- tokens.consumeEnd(); |
- return new Branch(cond, trueCont, falseCont); |
- } |
- |
- /// (ConcatenateStrings (args) cont) |
- ConcatenateStrings parseConcatenateStrings() { |
- tokens.consumeStart(CONCATENATE_STRINGS); |
- |
- List<Primitive> args = parsePrimitiveList(); |
- |
- Continuation cont = name2variable[tokens.read()]; |
- assert(cont != null); |
- |
- tokens.consumeEnd(); |
- return new ConcatenateStrings(args, cont); |
- } |
- |
- /// (DeclareFunction name = function in body) |
- DeclareFunction parseDeclareFunction() { |
- tokens.consumeStart(DECLARE_FUNCTION); |
- |
- // name = |
- MutableVariable local = addMutableVariable(tokens.read()); |
- tokens.read("="); |
- |
- // function in |
- FunctionDefinition def = parseFunctionDefinition(); |
- tokens.read("in"); |
- |
- // body |
- Expression body = parseExpression(); |
- |
- tokens.consumeEnd(); |
- return new DeclareFunction(local, def)..plug(body); |
- } |
- |
- /// (InvokeConstructor name (args) cont) |
- InvokeConstructor parseInvokeConstructor() { |
- tokens.consumeStart(INVOKE_CONSTRUCTOR); |
- |
- String constructorName = tokens.read(); |
- List<String> split = constructorName.split("."); |
- assert(split.length < 3); |
- |
- dart_types.DartType type = new DummyNamedType(split[0]); |
- Element element = new DummyElement((split.length == 1) ? "" : split[1]); |
- |
- List<Primitive> args = parsePrimitiveList(); |
- |
- Continuation cont = name2variable[tokens.read()]; |
- assert(cont != null); |
- |
- tokens.consumeEnd(); |
- Selector selector = dummySelector(constructorName, args.length); |
- return new InvokeConstructor(type, element, selector, args, cont); |
- } |
- |
- /// (InvokeContinuation rec? name (args)) |
- InvokeContinuation parseInvokeContinuation() { |
- tokens.consumeStart(INVOKE_CONTINUATION); |
- String name = tokens.read(); |
- bool isRecursive = name == "rec"; |
- if (isRecursive) name = tokens.read(); |
- |
- Continuation cont = name2variable[name]; |
- assert(cont != null); |
- |
- List<Primitive> args = parsePrimitiveList(); |
- |
- tokens.consumeEnd(); |
- return new InvokeContinuation(cont, args, isRecursive: isRecursive); |
- } |
- |
- /// (InvokeMethod receiver method (args) cont) |
- InvokeMethod parseInvokeMethod() { |
- tokens.consumeStart(INVOKE_METHOD); |
- |
- Definition receiver = name2variable[tokens.read()]; |
- assert(receiver != null); |
- |
- String methodName = tokens.read(); |
- |
- List<Primitive> args = parsePrimitiveList(); |
- |
- Continuation cont = name2variable[tokens.read()]; |
- assert(cont != null); |
- |
- tokens.consumeEnd(); |
- Selector selector = dummySelector(methodName, args.length); |
- return new InvokeMethod(receiver, selector, args, cont); |
- } |
- |
- /// (InvokeStatic method (args) cont) |
- InvokeStatic parseInvokeStatic() { |
- tokens.consumeStart(INVOKE_STATIC); |
- |
- String methodName = tokens.read(); |
- |
- List<Primitive> args = parsePrimitiveList(); |
- |
- Continuation cont = name2variable[tokens.read()]; |
- assert(cont != null); |
- |
- Entity entity = new DummyEntity(methodName); |
- Selector selector = dummySelector(methodName, args.length); |
- |
- tokens.consumeEnd(); |
- return new InvokeStatic(entity, selector, args, cont, null); |
- } |
- |
- /// (InvokeMethodDirectly receiver method (args) cont) |
- InvokeMethodDirectly parseInvokeMethodDirectly() { |
- tokens.consumeStart(INVOKE_METHOD_DIRECTLY); |
- |
- Definition receiver = name2variable[tokens.read()]; |
- assert(receiver != null); |
- |
- String methodName = tokens.read(); |
- |
- List<Primitive> args = parsePrimitiveList(); |
- |
- Continuation cont = name2variable[tokens.read()]; |
- assert(cont != null); |
- |
- tokens.consumeEnd(); |
- Element element = new DummyElement(methodName); |
- Selector selector = dummySelector(methodName, args.length); |
- return new InvokeMethodDirectly(receiver, element, selector, args, cont); |
- } |
- |
- // (rec? name (args) body) |
- Continuation parseContinuation() { |
- // (rec? name |
- tokens.consumeStart(); |
- String name = tokens.read(); |
- bool isRecursive = name == "rec"; |
- if (isRecursive) name = tokens.read(); |
- |
- // (args) |
- tokens.consumeStart(); |
- List<Parameter> params = <Parameter>[]; |
- while (tokens.current != ")") { |
- String paramName = tokens.read(); |
- Parameter param = new Parameter(new DummyElement(paramName)); |
- name2variable[paramName] = param; |
- params.add(param); |
- } |
- tokens.consumeEnd(); |
- |
- Continuation cont = new Continuation(params); |
- name2variable[name] = cont; |
- |
- cont.isRecursive = isRecursive; |
- // cont_body |
- cont.body = parseExpression(); |
- tokens.consumeEnd(); |
- return cont; |
- } |
- |
- /// (LetCont (continuations) body) |
- LetCont parseLetCont() { |
- tokens.consumeStart(LET_CONT); |
- tokens.consumeStart(); |
- List<Continuation> continuations = <Continuation>[]; |
- while (tokens.current != ")") { |
- continuations.add(parseContinuation()); |
- } |
- tokens.consumeEnd(); |
- |
- // body) |
- Expression body = parseExpression(); |
- tokens.consumeEnd(); |
- |
- return new LetCont.many(continuations, body); |
- } |
- |
- /// (LetMutable (name value) body) |
- LetMutable parseLetMutable() { |
- tokens.consumeStart(LET_MUTABLE); |
- |
- tokens.consumeStart(); |
- String name = tokens.read(); |
- MutableVariable local = addMutableVariable(name); |
- Primitive value = name2variable[tokens.read()]; |
- tokens.consumeEnd(); |
- |
- Expression body = parseExpression(); |
- tokens.consumeEnd(); |
- return new LetMutable(local, value)..plug(body); |
- } |
- |
- /// (SetMutable name value) |
- SetMutable parseSetMutable() { |
- tokens.consumeStart(SET_MUTABLE); |
- |
- MutableVariable local = name2variable[tokens.read()]; |
- Primitive value = name2variable[tokens.read()]; |
- assert(value != null); |
- |
- tokens.consumeEnd(); |
- return new SetMutable(local, value); |
- } |
- |
- /// (TypeCast value type args cont) |
- TypeCast parseTypeCast() { |
- tokens.consumeStart(TYPE_CAST); |
- |
- Primitive value = name2variable[tokens.read()]; |
- assert(value != null); |
- |
- dart_types.DartType type = new DummyNamedType(tokens.read()); |
- |
- List<ir.Primitive> typeArguments = parsePrimitiveList(); |
- |
- Continuation cont = name2variable[tokens.read()]; |
- assert(cont != null); |
- |
- tokens.consumeEnd(); |
- return new TypeCast(value, type, typeArguments, cont); |
- } |
- |
- /// (TypeTest value type args) |
- TypeTest parseTypeTest() { |
- tokens.consumeStart(TYPE_TEST); |
- |
- Primitive value = name2variable[tokens.read()]; |
- assert(value != null); |
- |
- dart_types.DartType type = new DummyNamedType(tokens.read()); |
- |
- List<ir.Primitive> typeArguments = parsePrimitiveList(); |
- |
- tokens.consumeEnd(); |
- return new TypeTest(value, type, typeArguments); |
- } |
- |
- /// (ApplyBuiltinOperator operator args) |
- ApplyBuiltinOperator parseApplyBuiltinOperator() { |
- tokens.consumeStart(APPLY_BUILTIN_OPERATOR); |
- |
- String operatorName = tokens.read(); |
- BuiltinOperator operator; |
- for (BuiltinOperator op in BuiltinOperator.values) { |
- if (op.toString() == operatorName) { |
- operator = op; |
- break; |
- } |
- } |
- assert(operator != null); |
- List<ir.Primitive> arguments = parsePrimitiveList(); |
- |
- tokens.consumeEnd(); |
- return new ApplyBuiltinOperator(operator, arguments); |
- } |
- |
- /// (GetLength object) |
- GetLength parseGetLength() { |
- tokens.consumeStart(GET_LENGTH); |
- Primitive object = name2variable[tokens.read()]; |
- tokens.consumeEnd(); |
- return new GetLength(object); |
- } |
- |
- /// (GetIndex object index) |
- GetIndex parseGetIndex() { |
- tokens.consumeStart(GET_INDEX); |
- Primitive object = name2variable[tokens.read()]; |
- Primitive index = name2variable[tokens.read()]; |
- tokens.consumeEnd(); |
- return new GetIndex(object, index); |
- } |
- |
- /// (SetIndex object index value) |
- SetIndex parseSetIndex() { |
- tokens.consumeStart(SET_INDEX); |
- Primitive object = name2variable[tokens.read()]; |
- Primitive index = name2variable[tokens.read()]; |
- Primitive value = name2variable[tokens.read()]; |
- tokens.consumeEnd(); |
- return new SetIndex(object, index, value); |
- } |
- |
- /// (SetStatic field value) |
- SetStatic parseSetStatic() { |
- tokens.consumeStart(SET_STATIC); |
- |
- Element fieldElement = new DummyElement(tokens.read()); |
- Primitive value = name2variable[tokens.read()]; |
- assert(value != null); |
- |
- tokens.consumeEnd(); |
- return new SetStatic(fieldElement, value, null); |
- } |
- |
- /// (GetLazyStatic field cont) |
- GetLazyStatic parseGetLazyStatic() { |
- tokens.consumeStart(GET_LAZY_STATIC); |
- |
- Element fieldElement = new DummyElement(tokens.read()); |
- Continuation cont = name2variable[tokens.read()]; |
- assert(cont != null); |
- |
- tokens.consumeEnd(); |
- return new GetLazyStatic(fieldElement, cont, null); |
- } |
- |
- /// (Unreachable) |
- Unreachable parseUnreachable() { |
- tokens.consumeStart(UNREACHABLE); |
- tokens.consumeEnd(); |
- return new Unreachable(); |
- } |
- |
- /// (LetPrim (name primitive) body) |
- LetPrim parseLetPrim() { |
- tokens.consumeStart(LET_PRIM); |
- |
- // (name |
- tokens.consumeStart(); |
- String name = tokens.read(); |
- |
- // primitive) |
- Primitive primitive = parsePrimitive(); |
- name2variable[name] = primitive; |
- tokens.consumeEnd(); |
- |
- // body) |
- Expression body = parseExpression(); |
- tokens.consumeEnd(); |
- |
- return new LetPrim(primitive)..plug(body); |
- } |
- |
- Primitive parsePrimitive() { |
- assert(tokens.current == "("); |
- |
- switch (tokens.next) { |
- case CONSTANT: |
- return parseConstant(); |
- case CREATE_FUNCTION: |
- return parseCreateFunction(); |
- case GET_MUTABLE: |
- return parseGetMutable(); |
- case SET_MUTABLE: |
- return parseSetMutable(); |
- case LITERAL_LIST: |
- return parseLiteralList(); |
- case LITERAL_MAP: |
- return parseLiteralMap(); |
- case REIFY_TYPE_VAR: |
- return parseReifyTypeVar(); |
- case GET_STATIC: |
- return parseGetStatic(); |
- case SET_STATIC: |
- return parseSetStatic(); |
- case TYPE_TEST: |
- return parseTypeTest(); |
- case APPLY_BUILTIN_OPERATOR: |
- return parseApplyBuiltinOperator(); |
- case GET_LENGTH: |
- return parseGetLength(); |
- case GET_INDEX: |
- return parseGetIndex(); |
- case SET_INDEX: |
- return parseSetIndex(); |
- case GET_FIELD: |
- return parseGetField(); |
- case SET_FIELD: |
- return parseSetField(); |
- default: |
- assert(false); |
- } |
- |
- return null; |
- } |
- |
- /// (Constant (constant)) |
- Constant parseConstant() { |
- tokens.consumeStart(CONSTANT); |
- tokens.consumeStart(); |
- Constant result; |
- String tag = tokens.read(); |
- switch (tag) { |
- case NULL: |
- result = new Constant( |
- new NullConstantExpression(new NullConstantValue())); |
- break; |
- case BOOL: |
- String value = tokens.read(); |
- if (value == "true") { |
- result = new Constant( |
- new BoolConstantExpression(true, new TrueConstantValue())); |
- } else if (value == "false") { |
- result = new Constant( |
- new BoolConstantExpression(false, new FalseConstantValue())); |
- } else { |
- throw "Invalid Boolean value '$value'."; |
- } |
- break; |
- case STRING: |
- List<String> strings = <String>[]; |
- do { |
- strings.add(tokens.read()); |
- } while (tokens.current != ")"); |
- String string = strings.join(" "); |
- assert(string.startsWith('"') && string.endsWith('"')); |
- String text = string.substring(1, string.length - 1); |
- StringConstantValue value = new StringConstantValue( |
- new LiteralDartString(text)); |
- result = new Constant(new StringConstantExpression(text, value)); |
- break; |
- case INT: |
- String value = tokens.read(); |
- int intValue = int.parse(value, onError: (_) => null); |
- if (intValue == null) { |
- throw "Invalid int value 'value'."; |
- } |
- result = new Constant(new IntConstantExpression( |
- intValue, new IntConstantValue(intValue))); |
- break; |
- case DOUBLE: |
- String value = tokens.read(); |
- double doubleValue = double.parse(value, (_) => null); |
- if (doubleValue == null) { |
- throw "Invalid double value '$value'."; |
- } |
- result = new Constant(new DoubleConstantExpression( |
- doubleValue, new DoubleConstantValue(doubleValue))); |
- break; |
- default: |
- throw "Unexpected constant tag '$tag'."; |
- } |
- tokens.consumeEnd(); |
- tokens.consumeEnd(); |
- return result; |
- } |
- |
- /// (CreateFunction (definition)) |
- CreateFunction parseCreateFunction() { |
- tokens.consumeStart(CREATE_FUNCTION); |
- FunctionDefinition def = parseFunctionDefinition(); |
- tokens.consumeEnd(); |
- return new CreateFunction(def); |
- } |
- |
- MutableVariable addMutableVariable(String name) { |
- assert(!name2variable.containsKey(name)); |
- MutableVariable variable = new MutableVariable(new DummyElement(name)); |
- name2variable[name] = variable; |
- return variable; |
- } |
- |
- /// (GetMutable name) |
- GetMutable parseGetMutable() { |
- tokens.consumeStart(GET_MUTABLE); |
- MutableVariable local = name2variable[tokens.read()]; |
- tokens.consumeEnd(); |
- |
- return new GetMutable(local); |
- } |
- |
- /// (LiteralList (values)) |
- LiteralList parseLiteralList() { |
- tokens.consumeStart(LITERAL_LIST); |
- List<Primitive> values = parsePrimitiveList(); |
- tokens.consumeEnd(); |
- return new LiteralList(null, values); |
- } |
- |
- /// (LiteralMap (keys) (values)) |
- LiteralMap parseLiteralMap() { |
- tokens.consumeStart(LITERAL_MAP); |
- |
- List<Primitive> keys = parsePrimitiveList(); |
- List<Primitive> values = parsePrimitiveList(); |
- |
- List<LiteralMapEntry> entries = <LiteralMapEntry>[]; |
- for (int i = 0; i < keys.length; i++) { |
- entries.add(new LiteralMapEntry(keys[i], values[i])); |
- } |
- |
- tokens.consumeEnd(); |
- return new LiteralMap(null, entries); |
- } |
- |
- /// (ReifyTypeVar type) |
- ReifyTypeVar parseReifyTypeVar() { |
- tokens.consumeStart(REIFY_TYPE_VAR); |
- |
- TypeVariableElement type = new DummyElement(tokens.read()); |
- |
- tokens.consumeEnd(); |
- return new ReifyTypeVar(type); |
- } |
- |
- /// (GetStatic field) |
- GetStatic parseGetStatic() { |
- tokens.consumeStart(GET_STATIC); |
- |
- Element field = new DummyElement(tokens.read()); |
- |
- tokens.consumeEnd(); |
- return new GetStatic(field, null); |
- } |
- |
- /// (GetField object field) |
- GetField parseGetField() { |
- tokens.consumeStart(GET_FIELD); |
- |
- Primitive object = name2variable[tokens.read()]; |
- Element field = new DummyElement(tokens.read()); |
- |
- tokens.consumeEnd(); |
- return new GetField(object, field); |
- } |
- |
- /// (SetField object field value) |
- SetField parseSetField() { |
- tokens.consumeStart(SET_FIELD); |
- |
- Primitive object = name2variable[tokens.read()]; |
- Element field = new DummyElement(tokens.read()); |
- Primitive value = name2variable[tokens.read()]; |
- |
- tokens.consumeEnd(); |
- return new SetField(object, field, value); |
- } |
-} |