3 new revisions:
Revision: 8023b0a804
Author: Alex Eagle <
alex...@google.com>
Date: Thu Dec 3 21:26:31 2009
Log: We now execute a binding from the command line rather than a
concrete ...
http://code.google.com/p/noop/source/detail?r=8023b0a804
Revision: 2fd1e6fed2
Author: Alex Eagle <
alex...@google.com>
Date: Thu Dec 3 21:44:41 2009
Log: Fix the TODO: only concrete class definition has parameters.
http://code.google.com/p/noop/source/detail?r=2fd1e6fed2
Revision: 1f76fcbf5c
Author: Alex Eagle <
alex...@google.com>
Date: Thu Dec 3 21:48:53 2009
Log: Merge from Jeremie
http://code.google.com/p/noop/source/detail?r=1f76fcbf5c
==============================================================================
Revision: 8023b0a804
Author: Alex Eagle <
alex...@google.com>
Date: Thu Dec 3 21:26:31 2009
Log: We now execute a binding from the command line rather than a concrete
class. We must add a binding file for even a trivial application, which is
annoying. Perhaps we can find a concise way to run these apps which require
no user-specified bindings, but no real apps would be like that.
Also refactor the AST so that interface, binding, and concrete class are
different types, with class as their common parent.
http://code.google.com/p/noop/source/detail?r=8023b0a804
Added:
/core/src/main/scala/noop/model/BindingDefinition.scala
/core/src/main/scala/noop/model/ConcreteClassDefinition.scala
/core/src/main/scala/noop/model/InterfaceDefinition.scala
/examples/noop/arithmetic/ArithmeticBinding.noop
/examples/noop/commandLine/CommandLineApp.noop
/examples/noop/commandLine/CommandLineExample.noop
/examples/noop/controlFlow/WhileLoopBinding.noop
/examples/noop/helloworld/HelloWorldBinding.noop
Modified:
/core/src/main/antlr3/noop/grammar/antlr/NoopAST.g
/core/src/main/scala/noop/model/BindingDeclaration.scala
/core/src/main/scala/noop/model/ClassDefinition.scala
/core/src/main/scala/noop/model/LoggingAstVisitor.scala
/core/src/test/scala/noop/grammar/BindingSpec.scala
/core/src/test/scala/noop/grammar/ClassSpec.scala
/examples/noop/injection/start_injection.sh
/interpreter/src/main/scala/noop/inject/GuiceBackedInjector.scala
/interpreter/src/main/scala/noop/interpreter/Interpreter.scala
/interpreter/src/main/scala/noop/interpreter/InterpreterMain.scala
/interpreter/src/main/scala/noop/interpreter/SourceFileClassLoader.scala
/interpreter/src/test/scala/noop/interpreter/ExampleIntegrationTest.scala
/interpreter/src/test/scala/noop/interpreter/InterpreterSpec.scala
/interpreter/src/test/scala/noop/interpreter/InterpreterSystemTest.scala
/interpreter/src/test/scala/noop/interpreter/SourceFileClassLoaderSpec.scala
=======================================
--- /dev/null
+++ /core/src/main/scala/noop/model/BindingDefinition.scala Thu Dec 3
21:26:31 2009
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package noop.model
+
+import scala.collection.mutable.{ArrayBuffer, Buffer};
+
+/**
+ * AST element representing a top-level bindings definition
+ * @author Alex Eagle (
alex...@google.com)
+ */
+class BindingDefinition(name: String, namespace: String, documentation:
String)
+ extends ClassDefinition(name, namespace, documentation) {
+ val bindings: Buffer[BindingDeclaration] = new
ArrayBuffer[BindingDeclaration];
+
+}
=======================================
--- /dev/null
+++ /core/src/main/scala/noop/model/ConcreteClassDefinition.scala Thu Dec
3 21:26:31 2009
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package noop.model
+
+import scala.collection.mutable.{ArrayBuffer, Buffer};
+
+/**
+ * An AST element representing a concrete class. To the user, this is
a "class", but to us,
+ * a class may be an interface or a binding as well. This is similar to
Java's confusion
+ * but it's familiar.
+ *
+ * @author Alex Eagle (
alex...@google.com)
+ */
+
+class ConcreteClassDefinition(name: String, namespace: String,
documentation: String)
+ extends ClassDefinition(name, namespace, documentation) {
+ val interfaces: Buffer[String] = new ArrayBuffer[String];
+
+}
=======================================
--- /dev/null
+++ /core/src/main/scala/noop/model/InterfaceDefinition.scala Thu Dec 3
21:26:31 2009
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package noop.model
+
+/**
+ * AST model element for an interface.
+ * @author Alex Eagle (
alex...@google.com)
+ */
+
+class InterfaceDefinition(name: String, namespace: String, documentation:
String)
+ extends ClassDefinition(name, namespace, documentation) {
+
+}
=======================================
--- /dev/null
+++ /examples/noop/arithmetic/ArithmeticBinding.noop Thu Dec 3 21:26:31
2009
@@ -0,0 +1,23 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+namespace arithmetic;
+
+import arithmetic.Arithmetic;
+import noop.Application;
+
+binding ArithmeticBinding {
+ Application -> Arithmetic;
+}
=======================================
--- /dev/null
+++ /examples/noop/commandLine/CommandLineApp.noop Thu Dec 3 21:26:31 2009
@@ -0,0 +1,22 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+namespace commandLine;
+
+class CommandLineApp(RawCommandLineArguments args, Console console)
implements Application {
+ Int main() {
+ console.println(args(0));
+ }
+}
=======================================
--- /dev/null
+++ /examples/noop/commandLine/CommandLineExample.noop Thu Dec 3 21:26:31
2009
@@ -0,0 +1,20 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+namespace commandLine;
+
+binding CommandLineExample {
+ Application -> CommandLineApp;
+}
=======================================
--- /dev/null
+++ /examples/noop/controlFlow/WhileLoopBinding.noop Thu Dec 3 21:26:31
2009
@@ -0,0 +1,23 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+namespace controlFlow;
+
+import controlFlow.WhileLoop;
+import noop.Application;
+
+binding WhileLoopBinding {
+ Application -> WhileLoop;
+}
=======================================
--- /dev/null
+++ /examples/noop/helloworld/HelloWorldBinding.noop Thu Dec 3 21:26:31
2009
@@ -0,0 +1,23 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+namespace helloWorld;
+
+import helloWorld.HelloWorld;
+import noop.Application;
+
+binding HelloWorldBinding {
+ Application -> HelloWorld;
+}
=======================================
--- /core/src/main/antlr3/noop/grammar/antlr/NoopAST.g Wed Nov 25 15:40:07
2009
+++ /core/src/main/antlr3/noop/grammar/antlr/NoopAST.g Thu Dec 3 21:26:31
2009
@@ -120,7 +120,7 @@
classBlock[methodCollector, unittestCollector]?
d=doc?)
{
- ClassDefinition classDef = new ClassDefinition($t.text,
$SourceFile::file.namespace(), $d.doc);
+ ConcreteClassDefinition classDef = new ConcreteClassDefinition($t.text,
$SourceFile::file.namespace(), $d.doc);
classDef.imports().\$plus\$plus\$eq($SourceFile::file.imports());
classDef.methods().\$plus\$plus\$eq(methodCollector);
classDef.unittests().\$plus\$plus\$eq(unittestCollector);
@@ -138,7 +138,7 @@
interfaceDefinition
: ^(INTERFACE m=modifiers? t=TypeIdentifier d=doc?)
{
- ClassDefinition classDef = new ClassDefinition($t.text,
$SourceFile::file.namespace(), $d.doc);
+ InterfaceDefinition classDef = new InterfaceDefinition($t.text,
$SourceFile::file.namespace(), $d.doc);
if ($m.modifiers != null) {
classDef.modifiers().\$plus\$plus\$eq($m.modifiers);
}
@@ -224,8 +224,9 @@
bindingsDefinition
: ^(BINDING t=TypeIdentifier d=doc? b=bindings)
{
- ClassDefinition classDef = new ClassDefinition($t.text,
$SourceFile::file.namespace(), $d.doc);
- classDef.bindings().\$plus\$plus\$eq($b.bindings);
+ BindingDefinition classDef = new BindingDefinition($t.text,
$SourceFile::file.namespace(), $d.doc);
+ classDef.bindings().\$plus\$plus\$eq($b.bindings);
+ classDef.imports().\$plus\$plus\$eq($SourceFile::file.imports());
$SourceFile::file.classDef_\$eq(classDef);
}
;
@@ -318,8 +319,8 @@
| ass=assignment
{ $exp = $ass.exp; }
| right=(VariableIdentifier|TypeIdentifier) a=arguments?
- { Expression left = new IdentifierExpression("this");
- if ($a.args != null) {
+ { if ($a.args != null) {
+ Expression left = new IdentifierExpression("this");
$exp = new MethodInvocationExpression(left, $right.text, $a.args);
} else {
$exp = new IdentifierExpression($right.text);
@@ -353,7 +354,7 @@
{
$args.\$plus\$eq($exp.exp);
}
- ;
+ ;
literal returns [Expression exp]
: i=INT
=======================================
--- /core/src/main/scala/noop/model/BindingDeclaration.scala Sat Nov 7
12:07:39 2009
+++ /core/src/main/scala/noop/model/BindingDeclaration.scala Thu Dec 3
21:26:31 2009
@@ -13,17 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package noop.model;
/**
* AST model element which represents a declaration of a binding from a
type to an expression.
* @author
alex...@google.com (Alex Eagle)
*/
-class BindingDeclaration(val noopType: String, val binding: Expression)
extends Expression {
+class BindingDeclaration(val noopType: String, val boundTo: Expression)
extends Expression {
def accept(visitor: Visitor) = {
- binding.accept(visitor);
+ boundTo.accept(visitor);
visitor.visit(this);
}
-}
+
+ override def toString() = noopType + " -> " + boundTo;
+}
=======================================
--- /core/src/main/scala/noop/model/ClassDefinition.scala Wed Nov 25
15:26:47 2009
+++ /core/src/main/scala/noop/model/ClassDefinition.scala Thu Dec 3
21:26:31 2009
@@ -15,9 +15,10 @@
*/
package noop.model;
-import noop.types.NoopObject;
-
-import scala.collection.mutable.{ArrayBuffer, Buffer, Map};
+import noop.types.NoopObject
+import org.slf4j.LoggerFactory;
+
+import scala.collection.mutable.{ArrayBuffer, Buffer};
/**
* namespace is mutable because we may infer the namespace from the
relative path of the file
@@ -26,14 +27,19 @@
* @author
toc...@gmail.com (Jeremie Lenfant-Engelmann)
*/
class ClassDefinition (val name: String, var namespace: String, val
documentation: String) {
-
+ // TODO(alex): parameters belongs on ConcreteClassDefinition
val parameters: Buffer[Parameter] = new ArrayBuffer[Parameter];
- val interfaces: Buffer[String] = new ArrayBuffer[String];
val methods: Buffer[Method] = new ArrayBuffer[Method];
val unittests: Buffer[Method] = new ArrayBuffer[Method];
val modifiers: Buffer[Modifier.Value] = new ArrayBuffer[Modifier.Value];
val imports: Buffer[String] = new ArrayBuffer[String];
- val bindings: Buffer[BindingDeclaration] = new
ArrayBuffer[BindingDeclaration];
+
+ def resolveType(noopType: String): String = {
+ imports.find((imp: String) => imp.split("\\.").last == noopType) match
{
+ case Some(qualifiedType) => return qualifiedType;
+ case None => throw new IllegalAccessError();
+ }
+ }
def findMethod(methodName: String): Method = {
methods.find(method =>
method.name == methodName) match {
=======================================
--- /core/src/main/scala/noop/model/LoggingAstVisitor.scala Sat Nov 7
12:07:39 2009
+++ /core/src/main/scala/noop/model/LoggingAstVisitor.scala Thu Dec 3
21:26:31 2009
@@ -95,6 +95,6 @@
}
def visit(bindingDeclaration: BindingDeclaration) = {
-
logger.info("binding {} to {}", bindingDeclaration.noopType,
bindingDeclaration.binding);
+
logger.info("binding {} to {}", bindingDeclaration.noopType,
bindingDeclaration.boundTo);
}
}
=======================================
--- /core/src/test/scala/noop/grammar/BindingSpec.scala Wed Nov 25 15:56:45
2009
+++ /core/src/test/scala/noop/grammar/BindingSpec.scala Thu Dec 3 21:26:31
2009
@@ -15,8 +15,9 @@
*/
package noop.grammar
-import noop.model.{StringLiteralExpression, IdentifierExpression};
-import org.scalatest.matchers.ShouldMatchers;
+
+import org.scalatest.matchers.ShouldMatchers
+import noop.model.{BindingDefinition, StringLiteralExpression,
IdentifierExpression};
import org.scalatest.Spec;
/**
@@ -36,10 +37,11 @@
parser.parseFile(source).toStringTree() should be(
"(BINDING Something (BIND BankService BankServiceImpl) (BIND Port
9876) (BIND Max firstThing))");
val file = parser.buildTreeParser(parser.parseFile(source)).file;
- file.classDef.bindings should have length(3);
- file.classDef.bindings.first.noopType should be("BankService");
- file.classDef.bindings.first.binding.getClass() should
be(classOf[IdentifierExpression]);
-
file.classDef.bindings.first.binding.asInstanceOf[IdentifierExpression].identifier
should be ("BankServiceImpl");
+ val bindingDef = file.classDef.asInstanceOf[BindingDefinition];
+ bindingDef.bindings should have length(3);
+ bindingDef.bindings.first.noopType should be("BankService");
+ bindingDef.bindings.first.boundTo.getClass() should
be(classOf[IdentifierExpression]);
+
bindingDef.bindings.first.boundTo.asInstanceOf[IdentifierExpression].identifier
should be ("BankServiceImpl");
}
it("can appear as an anonymous binding block") {
@@ -52,8 +54,8 @@
method.block.namedBinding should be(None);
val firstBinding = method.block.anonymousBindings.first;
firstBinding.noopType should be("A");
- firstBinding.binding.getClass() should
be(classOf[IdentifierExpression]);
- firstBinding.binding.asInstanceOf[IdentifierExpression].identifier
should be ("B");
+ firstBinding.boundTo.getClass() should
be(classOf[IdentifierExpression]);
+ firstBinding.boundTo.asInstanceOf[IdentifierExpression].identifier
should be ("B");
}
@@ -102,8 +104,8 @@
method.block.anonymousBindings should have length(1);
val firstBinding = method.block.anonymousBindings.first;
firstBinding.noopType should be("String");
- firstBinding.binding.getClass() should
be(classOf[StringLiteralExpression]);
- firstBinding.binding.asInstanceOf[StringLiteralExpression].value
should be ("foo");
+ firstBinding.boundTo.getClass() should
be(classOf[StringLiteralExpression]);
+ firstBinding.boundTo.asInstanceOf[StringLiteralExpression].value
should be ("foo");
}
}
=======================================
--- /core/src/test/scala/noop/grammar/ClassSpec.scala Fri Nov 13 11:55:04
2009
+++ /core/src/test/scala/noop/grammar/ClassSpec.scala Thu Dec 3 21:26:31
2009
@@ -15,10 +15,11 @@
*/
package noop.grammar;
-import org.scalatest.matchers.ShouldMatchers;
+import org.scalatest.matchers.ShouldMatchers
+import noop.model.{ConcreteClassDefinition, Modifier};
import org.scalatest.Spec;
-import noop.model.Modifier;
+
/**
* @author
alex...@google.com (Alex Eagle)
@@ -94,9 +95,10 @@
"(CLASS Foo (IMPL A) (IMPL a b C) (IMPL d E))");
val file = parser.file(source);
file.classDef.name should be ("Foo");
- file.classDef.interfaces(0) should be("A");
- file.classDef.interfaces(1) should be ("a.b.C");
- file.classDef.interfaces(2) should be ("d.E");
+ val concreteDef =
file.classDef.asInstanceOf[ConcreteClassDefinition];
+ concreteDef.interfaces(0) should be("A");
+ concreteDef.interfaces(1) should be ("a.b.C");
+ concreteDef.interfaces(2) should be ("d.E");
}
it("should allow the native modifier on a class") {
=======================================
--- /examples/noop/injection/start_injection.sh Wed Nov 25 15:56:45 2009
+++ /examples/noop/injection/start_injection.sh Thu Dec 3 21:26:31 2009
@@ -1,1 +1,2 @@
+#!/bin/sh
noop injection.Injection --server
http://google.com
=======================================
--- /interpreter/src/main/scala/noop/inject/GuiceBackedInjector.scala Fri
Nov 13 16:27:54 2009
+++ /interpreter/src/main/scala/noop/inject/GuiceBackedInjector.scala Thu
Dec 3 21:26:31 2009
@@ -38,7 +38,7 @@
}
for (param <- classDef.parameters) {
- val paramClassDef = classLoader.findClass(param.noopType);
+ val paramClassDef =
classLoader.findClass(classDef.resolveType(param.noopType));
obj.propertyMap += Pair(
param.name, getInstance(paramClassDef));
}
return obj;
=======================================
--- /interpreter/src/main/scala/noop/interpreter/Interpreter.scala Sat Nov
21 16:11:59 2009
+++ /interpreter/src/main/scala/noop/interpreter/Interpreter.scala Thu Dec
3 21:26:31 2009
@@ -20,8 +20,6 @@
import noop.inject.{Injector, GuiceBackedInjector}
import noop.model._
-
-
/**
* This class bootstraps the interpretation process, by setting up the
ClassLoader with
* native Scala-implemented Noop types, and starting off the first method
invocation.
@@ -31,11 +29,27 @@
*/
class Interpreter @Inject() (classLoader: ClassLoader, injector: Injector,
context: Context, visitor: Visitor) {
- def runApplication(mainClass: ClassDefinition): Int = {
+ def runApplication(bindingDefinition: BindingDefinition): Int = {
+ // TODO(alex): Register bindings with the injector, then request an
instance of noop.Application
+ bindingDefinition.bindings.find((b: BindingDeclaration) => b.noopType
== "Application") match {
+ case Some(binding: BindingDeclaration) => {
+ val applicationType =
binding.boundTo.asInstanceOf[IdentifierExpression].identifier;
+ val applicationClass =
classLoader.findClass(bindingDefinition.resolveType(applicationType));
+ applicationClass match {
+ case concrete: ConcreteClassDefinition =>
runFromConcrete(concrete);
+ case _ => throw new IllegalStateException("Application must be
bound to concrete class");
+ }
+ }
+ case None => throw new IllegalStateException("No binding for
Application was found");
+ }
+ }
+
+ def runFromConcrete(mainClass: ConcreteClassDefinition): Int = {
val mainInstance = injector.getInstance(mainClass);
context.addRootFrame(mainInstance);
new MethodInvocationExpression(new
EvaluatedExpression(mainInstance), "main", List()).accept(visitor);
+ // TODO(alex): return the value from the main
return 0;
}
}
=======================================
--- /interpreter/src/main/scala/noop/interpreter/InterpreterMain.scala Sat
Nov 21 20:33:09 2009
+++ /interpreter/src/main/scala/noop/interpreter/InterpreterMain.scala Thu
Dec 3 21:26:31 2009
@@ -15,7 +15,8 @@
*/
package noop.interpreter;
-import com.google.inject.Guice;
+import com.google.inject.Guice
+import model.BindingDefinition;
import noop.types.NoopTypesModule;
/**
@@ -42,9 +43,13 @@
val sourcePaths = args.toList.tail + System.getProperty("user.dir");
val injector = Guice.createInjector(new
InterpreterModule(sourcePaths), new NoopTypesModule());
val mainClass =
injector.getInstance(classOf[ClassLoader]).findClass(args(0));
- val returnVal =
injector.getInstance(classOf[Interpreter]).runApplication(mainClass);
-
- exit(returnVal);
+ mainClass match {
+ case binding: BindingDefinition => {
+ val returnVal =
injector.getInstance(classOf[Interpreter]).runApplication(binding);
+ exit(returnVal);
+ }
+ case _ => throw new IllegalArgumentException("Can only run a
binding");
+ }
}
}
=======================================
---
/interpreter/src/main/scala/noop/interpreter/SourceFileClassLoader.scala
Tue Nov 17 18:47:39 2009
+++
/interpreter/src/main/scala/noop/interpreter/SourceFileClassLoader.scala
Thu Dec 3 21:26:31 2009
@@ -15,15 +15,12 @@
*/
package noop.interpreter;
-
-
import collection.mutable.Map
import java.io.{InputStream, FileInputStream, File}
-import model.{Parameter, ClassDefinition};
import org.slf4j.LoggerFactory;
-import grammar.{ParseException, Parser};
-
+import noop.model.{Parameter, ClassDefinition};
+import noop.grammar.{ParseException, Parser};
/**
* @author
alex...@google.com (Alex Eagle)
@@ -73,13 +70,6 @@
val parts = className.split("\\.");
classDef.namespace = parts.take(parts.size - 1).mkString(".");
}
- for (val param <- classDef.parameters) {
- for (val `import` <- classDef.imports) {
- if (`import`.split("\\.").last == param.noopType) {
- param.noopType = `import`;
- }
- }
- }
return classDef;
}
=======================================
---
/interpreter/src/test/scala/noop/interpreter/ExampleIntegrationTest.scala
Sat Nov 21 20:33:09 2009
+++
/interpreter/src/test/scala/noop/interpreter/ExampleIntegrationTest.scala
Thu Dec 3 21:26:31 2009
@@ -17,6 +17,7 @@
import com.google.inject.Guice
import java.io.File
+import model.BindingDefinition
import noop.types.NoopTypesModule;
import org.scalatest.matchers.ShouldMatchers;
@@ -46,10 +47,10 @@
it("should run the hello world program") {
withRedirectedStandardOut { (output) => {
val classLoader = createFixture;
- val mainClass = classLoader.findClass("HelloWorld");
+ val mainClass = classLoader.findClass("HelloWorldBinding");
mainClass should not be(null);
-
createInjector().getInstance(classOf[Interpreter]).runApplication(mainClass);
+
createInjector().getInstance(classOf[Interpreter]).runApplication(mainClass.asInstanceOf[BindingDefinition]);
output.toString() should include("Hello World!");
}}
}
@@ -57,8 +58,8 @@
it("should run while loop") {
withRedirectedStandardOut { (output) => {
val classLoader = createFixture;
- val mainClass = classLoader.findClass("WhileLoop");
-
createInjector().getInstance(classOf[Interpreter]).runApplication(mainClass);
+ val mainClass = classLoader.findClass("WhileLoopBinding");
+
createInjector().getInstance(classOf[Interpreter]).runApplication(mainClass.asInstanceOf[BindingDefinition]);
output.toString() should equal("Hello World!\n");
}}
}
@@ -66,8 +67,8 @@
it("should run the arithmetic program") {
withRedirectedStandardOut { (output) => {
val classLoader = createFixture;
- val mainClass = classLoader.findClass("Arithmetic");
-
createInjector().getInstance(classOf[Interpreter]).runApplication(mainClass);
+ val mainClass = classLoader.findClass("ArithmeticBinding");
+
createInjector().getInstance(classOf[Interpreter]).runApplication(mainClass.asInstanceOf[BindingDefinition]);
output.toString() should include("3");
}}
}
=======================================
--- /interpreter/src/test/scala/noop/interpreter/InterpreterSpec.scala Fri
Nov 13 11:55:04 2009
+++ /interpreter/src/test/scala/noop/interpreter/InterpreterSpec.scala Thu
Dec 3 21:26:31 2009
@@ -15,13 +15,13 @@
*/
package noop.interpreter;
-import inject.{GuiceBackedInjector, Injector};
-import model.{Visitor, IntLiteralExpression, OperatorExpression};
-import types.{NoopTypesModule, NoopObject, IntegerFactory, NoopInteger};
-import grammar.Parser;
-
-import java.io.{ByteArrayOutputStream, File};
+
+import noop.inject.Injector
+import noop.types.{NoopObject, NoopTypesModule, NoopInteger}
+import noop.model.{ClassDefinition, ConcreteClassDefinition, Visitor,
IntLiteralExpression, OperatorExpression}
import collection.mutable.Stack;
+import noop.grammar.Parser;
+
import com.google.inject.Guice;
import org.scalatest.matchers.ShouldMatchers;
import org.scalatest.Spec;
@@ -31,17 +31,16 @@
* @author
toc...@gmail.com (Jeremie Lenfant-Engelmann)
*/
class InterpreterSpec extends Spec with ShouldMatchers {
-
- def createFixture = {
- val injector = Guice.createInjector(new InterpreterModule(List()), new
NoopTypesModule());
- val context: Context = injector.getInstance(classOf[Context]);
- context.addRootFrame(null);
-
- (context, injector.getInstance(classOf[Visitor]));
-
- }
-
- describe("the interpreter") {
+ describe("integration tests for the interpreter") {
+
+ def createFixture = {
+ val injector = Guice.createInjector(new InterpreterModule(List()),
new NoopTypesModule());
+ val context: Context = injector.getInstance(classOf[Context]);
+ context.addRootFrame(null);
+
+ (context, injector.getInstance(classOf[Visitor]));
+
+ }
it("should evaluate simple arithmetic") {
val (context, visitor) = createFixture;
=======================================
---
/interpreter/src/test/scala/noop/interpreter/InterpreterSystemTest.scala
Sat Nov 21 20:56:22 2009
+++
/interpreter/src/test/scala/noop/interpreter/InterpreterSystemTest.scala
Thu Dec 3 21:26:31 2009
@@ -28,7 +28,7 @@
describe("the interpreter") {
it("should run successfully") {
withRedirectedStandardOut { (output) => {
-
InterpreterMain.main(List("helloworld.HelloWorld", "examples/noop").toArray);
+
InterpreterMain.main(List("helloworld.HelloWorldBinding", "examples/noop").toArray);
InterpreterMain.exitCodeForTesting should be(0);
}}
}
@@ -43,7 +43,7 @@
it("should use the working directory as a source root") {
withRedirectedStandardOut { (output) => {
-
InterpreterMain.main(List("examples.noop.helloworld.HelloWorld").toArray);
+
InterpreterMain.main(List("examples.noop.helloworld.HelloWorldBinding").toArray);
InterpreterMain.exitCodeForTesting should be(0);
}}
}
=======================================
---
/interpreter/src/test/scala/noop/interpreter/SourceFileClassLoaderSpec.scala
Tue Nov 17 18:47:39 2009
+++
/interpreter/src/test/scala/noop/interpreter/SourceFileClassLoaderSpec.scala
Thu Dec 3 21:26:31 2009
@@ -145,19 +145,5 @@
classDef.name should equal("Foo")
classDef.namespace should equal("namespace1")
}
-
- it("should replace parameter types with their fully-qualified
version") {
- val source = new File(tmpDir, "AnotherClass.noop");
- source.deleteOnExit();
- val printWriter = new PrintWriter(new FileWriter(source))
- printWriter.println("import namespace1.Foo; class AnotherClass(Foo
thing) {}");
- printWriter.close();
-
- val srcPaths = List(tmpDir.getAbsolutePath());
- val classLoader = new SourceFileClassLoader(new Parser(), srcPaths);
- val classDef = classLoader.findClass("AnotherClass")
-
- classDef.parameters.first.noopType should equal("namespace1.Foo")
- }
}
}
==============================================================================
Revision: 2fd1e6fed2
Author: Alex Eagle <
alex...@google.com>
Date: Thu Dec 3 21:44:41 2009
Log: Fix the TODO: only concrete class definition has parameters.
http://code.google.com/p/noop/source/detail?r=2fd1e6fed2
Modified:
/core/src/main/scala/noop/model/ClassDefinition.scala
/core/src/main/scala/noop/model/ConcreteClassDefinition.scala
/core/src/test/scala/noop/grammar/ClassSpec.scala
/interpreter/src/main/scala/noop/inject/GuiceBackedInjector.scala
=======================================
--- /core/src/main/scala/noop/model/ClassDefinition.scala Thu Dec 3
21:26:31 2009
+++ /core/src/main/scala/noop/model/ClassDefinition.scala Thu Dec 3
21:44:41 2009
@@ -27,8 +27,6 @@
* @author
toc...@gmail.com (Jeremie Lenfant-Engelmann)
*/
class ClassDefinition (val name: String, var namespace: String, val
documentation: String) {
- // TODO(alex): parameters belongs on ConcreteClassDefinition
- val parameters: Buffer[Parameter] = new ArrayBuffer[Parameter];
val methods: Buffer[Method] = new ArrayBuffer[Method];
val unittests: Buffer[Method] = new ArrayBuffer[Method];
val modifiers: Buffer[Modifier.Value] = new ArrayBuffer[Modifier.Value];
=======================================
--- /core/src/main/scala/noop/model/ConcreteClassDefinition.scala Thu Dec
3 21:26:31 2009
+++ /core/src/main/scala/noop/model/ConcreteClassDefinition.scala Thu Dec
3 21:44:41 2009
@@ -28,5 +28,5 @@
class ConcreteClassDefinition(name: String, namespace: String,
documentation: String)
extends ClassDefinition(name, namespace, documentation) {
val interfaces: Buffer[String] = new ArrayBuffer[String];
-
-}
+ val parameters: Buffer[Parameter] = new ArrayBuffer[Parameter];
+}
=======================================
--- /core/src/test/scala/noop/grammar/ClassSpec.scala Thu Dec 3 21:26:31
2009
+++ /core/src/test/scala/noop/grammar/ClassSpec.scala Thu Dec 3 21:44:41
2009
@@ -53,8 +53,9 @@
val file = parser.file(source);
file.classDef.name should be ("Bar");
- file.classDef.parameters(0).name should be ("a");
- file.classDef.parameters(0).noopType should be ("String");
+ val concreteClass =
file.classDef.asInstanceOf[ConcreteClassDefinition];
+ concreteClass.parameters(0).name should be ("a");
+ concreteClass.parameters(0).noopType should be ("String");
}
it("should parse a class with a fully-qualified type in a parameter") {
@@ -64,7 +65,8 @@
commonTree.toStringTree() should equal ("(CLASS Bar (PARAMS (PARAM
noop String a)))");
val file = parser.file(source);
- file.classDef.parameters(0).noopType should be ("noop.String");
+ val concreteClass =
file.classDef.asInstanceOf[ConcreteClassDefinition];
+ concreteClass.parameters(0).noopType should be ("noop.String");
}
it("should parse a class with multiple parameters") {
=======================================
--- /interpreter/src/main/scala/noop/inject/GuiceBackedInjector.scala Thu
Dec 3 21:26:31 2009
+++ /interpreter/src/main/scala/noop/inject/GuiceBackedInjector.scala Thu
Dec 3 21:44:41 2009
@@ -20,11 +20,12 @@
* @author
alex...@google.com (Alex Eagle)
*/
-import noop.model.ClassDefinition;
+
+import model.{ConcreteClassDefinition, ClassDefinition}
import noop.interpreter.ClassLoader;
import noop.types.{NoopConsole, NoopObject};
-import com.google.inject.{AbstractModule, Key};
+import com.google.inject.AbstractModule;
import scala.collection.mutable;
class GuiceBackedInjector(classLoader: ClassLoader, injector:
com.google.inject.Injector) extends Injector {
@@ -37,9 +38,12 @@
case _ => new NoopObject(classDef);
}
- for (param <- classDef.parameters) {
- val paramClassDef =
classLoader.findClass(classDef.resolveType(param.noopType));
- obj.propertyMap += Pair(
param.name, getInstance(paramClassDef));
+ if (classDef.isInstanceOf[ConcreteClassDefinition]) {
+ val concreteClass = classDef.asInstanceOf[ConcreteClassDefinition];
+ for (param <- concreteClass.parameters) {
+ val paramClassDef =
classLoader.findClass(classDef.resolveType(param.noopType));
+ obj.propertyMap += Pair(
param.name, getInstance(paramClassDef));
+ }
}
return obj;
}
==============================================================================
Revision: 1f76fcbf5c
Author: Alex Eagle <
alex...@google.com>
Date: Thu Dec 3 21:48:53 2009
Log: Merge from Jeremie
http://code.google.com/p/noop/source/detail?r=1f76fcbf5c
Modified:
/core/src/main/antlr3/noop/grammar/antlr/NoopAST.g
/core/src/main/scala/noop/model/LoggingAstVisitor.scala
/interpreter/src/main/scala/noop/interpreter/SourceFileClassLoader.scala
=======================================
--- /core/src/main/antlr3/noop/grammar/antlr/NoopAST.g Thu Dec 3 21:26:31
2009
+++ /core/src/main/antlr3/noop/grammar/antlr/NoopAST.g Thu Dec 3 21:48:53
2009
@@ -318,6 +318,8 @@
{ $exp = $o.exp; }
| ass=assignment
{ $exp = $ass.exp; }
+ | c=conditionalExpression
+ { $exp = $c.exp; }
| right=(VariableIdentifier|TypeIdentifier) a=arguments?
{ if ($a.args != null) {
Expression left = new IdentifierExpression("this");
@@ -327,9 +329,20 @@
}
}
;
+
+conditionalExpression returns [Expression exp]
+ : ^(cond=('||' | '&&') left=expression right=expression)
+ {
+ if ($cond.text.equals("||")) {
+ $exp = new ConditionalOrExpression($left.exp, $right.exp);
+ } else if ($cond.text.equals("&&")) {
+ $exp = new ConditionalAndExpression($left.exp, $right.exp);
+ }
+ }
+ ;
operatorExpression returns [Expression exp]
- : ^(op=('+'|'-'|'*'|'/'|'%') left=expression right=expression)
+ : ^(op=('+' | '-' | '*' | '/' | '%' | '==' | '!=' | '>' | '<' | '>='
| '<=') left=expression right=expression)
{ $exp = new OperatorExpression($left.exp, $op.text, $right.exp); }
;
=======================================
--- /core/src/main/scala/noop/model/LoggingAstVisitor.scala Thu Dec 3
21:26:31 2009
+++ /core/src/main/scala/noop/model/LoggingAstVisitor.scala Thu Dec 3
21:48:53 2009
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package noop.model
+package noop.model;
import org.slf4j.LoggerFactory;
@@ -97,4 +97,12 @@
def visit(bindingDeclaration: BindingDeclaration) = {
logger.info("binding {} to {}", bindingDeclaration.noopType,
bindingDeclaration.boundTo);
}
-}
+
+ def visit(conditionalAndExpression: ConditionalAndExpression) = {
+
logger.info("and conditional expression");
+ }
+
+ def visit(conditionalOrExpression: ConditionalOrExpression) = {
+
logger.info("or conditional expression");
+ }
+}