| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, the Dart 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 | |
| 6 #import('file_system.dart'); | |
| 7 #import('lang.dart'); | |
| 8 | |
| 9 interface JsEvaluator { | |
| 10 var eval(String source); | |
| 11 } | |
| 12 | |
| 13 class Evaluator { | |
| 14 JsEvaluator _jsEvaluator; | |
| 15 static String _prelude; | |
| 16 Library _lib; | |
| 17 | |
| 18 static void initWorld(String homedir, List<String> args, FileSystem files) { | |
| 19 parseOptions(homedir, args, files); | |
| 20 options.forceDynamic = true; | |
| 21 options.compileAll = true; | |
| 22 | |
| 23 initializeWorld(files); | |
| 24 world.process(); | |
| 25 world.resolveAll(); | |
| 26 | |
| 27 world.gen = new WorldGenerator(null, new CodeWriter()); | |
| 28 world.gen.markLibrariesUsed([world.coreimpl, world.corelib]); | |
| 29 | |
| 30 world.gen.writeTypes(world.coreimpl); | |
| 31 world.gen.writeTypes(world.corelib); | |
| 32 world.gen.writeGlobals(); | |
| 33 _prelude = world.gen.writer.text; | |
| 34 | |
| 35 // Set these here so that we can compile the corelib without its errors | |
| 36 // killing us | |
| 37 options.throwOnErrors = true; | |
| 38 options.throwOnFatal = true; | |
| 39 } | |
| 40 | |
| 41 _removeMember(String name) { | |
| 42 _lib.topType._resolvedMembers.remove(name); | |
| 43 _lib.topType.members.remove(name); | |
| 44 // Don't rely on the existing member's jsname, because the existing member | |
| 45 // may be null but the jsname may still be defined. This can happen if | |
| 46 // multiple Evaluators are instantiated against the same world. | |
| 47 var jsname = '${_lib.jsname}_$name'; | |
| 48 world._topNames.remove(name); | |
| 49 world._topNames.remove(jsname); | |
| 50 } | |
| 51 | |
| 52 Evaluator(JsEvaluator this._jsEvaluator) { | |
| 53 if (_prelude == null) { | |
| 54 throw new UnsupportedOperationException( | |
| 55 "Must call Evaluator.initWorld before creating a Evaluator."); | |
| 56 } | |
| 57 this._jsEvaluator.eval(_prelude); | |
| 58 _lib = new Library(new SourceFile("_ifrog_", "")); | |
| 59 _lib.imports.add(new LibraryImport(world.corelib)); | |
| 60 _lib.resolve(); | |
| 61 } | |
| 62 | |
| 63 void _ensureVariableDefined(Identifier name, | |
| 64 [List<Token> modifiers = const [], TypeReference type = null]) { | |
| 65 var member = _lib.topType.getMember(name.name); | |
| 66 if (member is FieldMember || member is PropertyMember) return; | |
| 67 _removeMember(name.name); | |
| 68 _lib.topType.addField( | |
| 69 new VariableDefinition(modifiers, type, [name], [null], name.span)); | |
| 70 _lib.topType.getMember(name.name).resolve(); | |
| 71 } | |
| 72 | |
| 73 var eval(String dart) { | |
| 74 var source = new SourceFile("_ifrog_", dart); | |
| 75 world.gen.writer = new CodeWriter(); | |
| 76 | |
| 77 var code; | |
| 78 var parsed = new Parser(source, throwOnIncomplete: true, | |
| 79 optionalSemicolons: true).evalUnit(); | |
| 80 var method = new MethodMember("_ifrog_dummy", _lib.topType, null); | |
| 81 var methGen = new MethodGenerator(method, null); | |
| 82 | |
| 83 if (parsed is ExpressionStatement) { | |
| 84 var body = parsed.body; | |
| 85 // Auto-declare variables that haven't been declared yet, so users can | |
| 86 // write "a = 1" rather than "var a = 1" | |
| 87 if (body is BinaryExpression && body.op.kind == TokenKind.ASSIGN && | |
| 88 body.x is VarExpression) { | |
| 89 _ensureVariableDefined(body.x.dynamic.name); | |
| 90 } | |
| 91 code = body.visit(methGen).code; | |
| 92 | |
| 93 } else if (parsed is VariableDefinition) { | |
| 94 var assignments = <Statement>[]; | |
| 95 zip(parsed.names, parsed.values, (name, value) { | |
| 96 _ensureVariableDefined(name, parsed.modifiers, parsed.type); | |
| 97 var expr = new BinaryExpression( | |
| 98 new Token.fake(TokenKind.ASSIGN, parsed.span), | |
| 99 new VarExpression(name, name.span), value, parsed.span); | |
| 100 new ExpressionStatement(expr, parsed.span).visit(methGen); | |
| 101 }); | |
| 102 code = methGen.writer.text; | |
| 103 | |
| 104 } else if (parsed is FunctionDefinition) { | |
| 105 var methodName = parsed.name.name; | |
| 106 _removeMember(methodName); | |
| 107 _lib.topType.addMethod(methodName, parsed); | |
| 108 MethodMember definedMethod = _lib.topType.getMember(methodName); | |
| 109 definedMethod.resolve(); | |
| 110 var definedMethGen = new MethodGenerator(definedMethod, null); | |
| 111 definedMethGen.run(); | |
| 112 definedMethGen.writeDefinition(world.gen.writer, null); | |
| 113 code = world.gen.writer.text; | |
| 114 } else if (parsed is TypeDefinition) { | |
| 115 _removeMember(parsed.name.name); | |
| 116 parsed.visit(new _LibraryVisitor(_lib)); | |
| 117 var type = _lib.findTypeByName(parsed.name.name); | |
| 118 type.resolve(); | |
| 119 world.gen.markTypeUsed(type); | |
| 120 world.gen.writeType(type); | |
| 121 code = '${world.gen.writer.text}; undefined'; | |
| 122 } else { | |
| 123 parsed.visit(methGen); | |
| 124 code = methGen.writer.text; | |
| 125 } | |
| 126 | |
| 127 world.gen.writer = new CodeWriter(); | |
| 128 world.gen.writeAllDynamicStubs([world.coreimpl, world.corelib, _lib]); | |
| 129 | |
| 130 return this._jsEvaluator.eval('${world.gen.writer.text}; $code'); | |
| 131 } | |
| 132 } | |
| OLD | NEW |