public void TestExpressionFunctionReturnTypeBinding() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " func Add(int a, int b) -> return new MyClass2()" + " }" + "" + " class MyClass2" + " {" + " " + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); var semanticModel = binder.Bind(new List<CompilationUnitSyntax> { ast }).Single(); var boundNamespace = semanticModel.Namespaces.Single(x => x.Name == "MyNamespace"); var expectedFunctionReturnType = boundNamespace.Types.Single(x => x.Name == "MyClass2"); var function = boundNamespace.Types.Single(x => x.Name == "MyClass").Functions.Single(x => x.Name == "Add"); Assert.AreSame(expectedFunctionReturnType, function.ReturnType); }
public Expressions Parse(string sourceText) //API entry point { ResetParserState(); sourceText += '\0'; //TOOD: figure out how newline is interpreted in a c# string m_Lexer.Lex(sourceText, Lexer.Lexer.IncludeWhiteSpaceTokens.No, Lexer.Lexer.IncludeEofToken.Yes); m_tokenList = m_Lexer.GetTokens(); if (m_Lexer.m_Diagnostics.Count > 0) { foreach (var errorMessage in m_Lexer.m_Diagnostics) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Lexer: " + errorMessage); Console.ResetColor(); } return(null); } switch (Peek().TokenType) { //ParseStatement,.... default: return(ParseExpression()); } }
public void TestClass() { var lexer = new Lexer.Lexer(); var tokens = lexer.Lex( string.Format(NamespaceSource, string.Format(ClassSource, string.Empty, string.Empty, string.Empty))); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); Assert.IsInstanceOf<CompilationUnitSyntax>(ast); Assert.IsNotEmpty(ast.Namespaces); Assert.IsNotEmpty(ast.Namespaces[0].Classes); Assert.AreEqual("ClassSample", ast.Namespaces[0].Classes[0].Name.Value); Assert.AreEqual("DSampleProtocol", ast.Namespaces[0].Classes[0].ProtocolName.Value); }
public void TestExpressionFunction() { const string functionSource = "func FunctionSample(int a, int b, int c) -> return a * b * c"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex( string.Format( NamespaceSource, string.Format(ClassSource, functionSource, string.Empty, string.Empty))); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); Assert.IsNotEmpty(ast.Namespaces[0].Classes[0].Functions); Assert.IsInstanceOf<FunctionSyntax>(ast.Namespaces[0].Classes[0].Functions[0]); Assert.AreEqual("FunctionSample", ast.Namespaces[0].Classes[0].Functions[0].Name.Value); }
public Parser(string text) { var tokens = new List <SyntaxToken>(); var lexer = new Lexer.Lexer(text); SyntaxToken token; do { token = lexer.Lex(); if (token.Kind != TokenType.Whitespace && token.Kind != TokenType.Bad) { tokens.Add(token); } } while (token.Kind != TokenType.EndOfFile); _tokens = tokens.ToArray(); _diagnostics.AddRange(lexer.Diagnostics); }
public void TestFieldTypeToVariableBinding() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " var field : false" + " var field2 : new MyClass2()" + " func MyFunc()" + " {" + " var i : field" + " var i2 : field2" + " }" + " }" + "" + " class MyClass2" + " {" + " " + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); var semanticModel = binder.Bind(new List<CompilationUnitSyntax> { ast }).Single(); var boundNamespace = semanticModel.Namespaces.Single(x => x.Name == "MyNamespace"); var referencedBoundType = boundNamespace.Types.Single(x => x.Name == "MyClass2"); var boundType = boundNamespace.Types.Single(x => x.Name == "MyClass"); var boundFunction = (BoundFunction)boundType.Functions.Single(x => x.Name == "MyFunc"); Assert.IsInstanceOf<BoolCompilerGeneratedType>( ((IBoundMember)((BoundScopeStatement)boundFunction.Statements).Statements[0]).Type); Assert.AreSame( ((IBoundMember)((BoundScopeStatement)boundFunction.Statements).Statements[1]).Type, referencedBoundType); }
public void Test_InfixCall_Types() { const string src = "namespace MyNamespace" + "{" + " class MyClass2" + " {" + " infix func Add(int a, int b) -> return a + b" + " func Foo()" + " {" + " var a : 1 Add 2" + " }" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); var boundCompilationUnits = binder.Bind(new List<CompilationUnitSyntax>() { ast }); var myClass2Type = boundCompilationUnits[0].Namespaces[0].Types.Single(); var fooFunction = myClass2Type.Functions.Single(x => x.Name == "Foo"); var addFunction = myClass2Type.Functions.Single(x => x.Name == "Add"); Assert.IsInstanceOf<BoundFunction>(addFunction); Assert.IsTrue(((BoundFunction)addFunction).IsInfixFunction); Assert.IsInstanceOf<BoundFunction>(fooFunction); var boundFunction = (BoundFunction)fooFunction; Assert.IsInstanceOf<BoundScopeStatement>(boundFunction.Statements); var boundScopeStatement = (BoundScopeStatement)boundFunction.Statements; Assert.IsInstanceOf<BoundVariableDeclarationStatement>(boundScopeStatement.Statements[0]); var boundVariableDeclarationStatement = (BoundVariableDeclarationStatement)boundScopeStatement.Statements[0]; Assert.IsInstanceOf<BoundInvocationExpression>(boundVariableDeclarationStatement.BoundExpression); var boundInvocationExpression = (BoundInvocationExpression)boundVariableDeclarationStatement.BoundExpression; Assert.IsInstanceOf<BoundMemberExpression>(boundInvocationExpression.ToInvoke); var boundMemberExpression = (BoundMemberExpression)boundInvocationExpression.ToInvoke; Assert.AreSame(addFunction, boundMemberExpression.BoundMember); }
public void Test_GenericConstraints(string constraint) { const string template = "class SomeGenericClass!(T) where T {0}"; var parserFunc = new Action<string>( opSrc => { var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(string.Format(template, opSrc)); var parser = new Parser.Parser(tokens); parser.Parse(); }); Assert.That(() => parserFunc(constraint), Throws.Nothing); }
public void Test_ArrayAccessInvalidParameter_Throws() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " func Add(int a, int b)" + " { " + " var c : new int[1][1]" + " var d : c[1]" + " }" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); Assert.That( () => binder.Bind(new List<CompilationUnitSyntax>() { ast }), Throws.InstanceOf<KiwiSemanticException>() .With.Message.EqualTo("Parameter count (1) must match array dimension count (2)")); }
public void Test_SwitchStatement_CasesTypeMustMatchSwitchConditionType() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " func Add(int a, int b) " + " { " + " switch(a)" + " {" + " case \"LOL\" -> Add(1, 0)" + " }" + " }" + " }" + "" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); Assert.That( () => binder.Bind(new List<CompilationUnitSyntax>() { ast }), Throws.InstanceOf<KiwiSemanticException>() .With.Message.EqualTo("Switch cases condition type must match switch condition type")); }
public void Test_RecursivExpressionFunction_DoesThrow() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " func Add(int a, int b) -> return Add(1, 2)" + " }" + "" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); Assert.That( () => binder.Bind(new List<CompilationUnitSyntax>() { ast }), Throws.InstanceOf<KiwiSemanticException>().With.Message.EqualTo("Add Type cannot be inferred")); }
public void Test_Operator_FunctionMapping() { const string src = "namespace MyNamespace" + "{" + " class MyClass2" + " {" + " operator Add(MyClass2 opA, MyClass2 opB) -> return new MyClass2()" + " operator Sub(MyClass2 opA, MyClass2 opB) -> return new MyClass2()" + " operator Mult(MyClass2 opA, MyClass2 opB) -> return new MyClass2()" + " operator Div(MyClass2 opA, MyClass2 opB) -> return new MyClass2()" + " operator Pow(MyClass2 opA, MyClass2 opB) -> return new MyClass2()" + " operator Range(MyClass2 opA, MyClass2 opB) -> return new MyClass2[1]" + " operator In(MyClass2 opA, MyClass2 opB) -> return true" + " }" + " " + " class TestClass" + " {" + " func TestBinaryFunc()" + " {" + " var instance : new MyClass2()" + " var testAdd : instance + new MyClass2()" + " var testSub : instance - new MyClass2()" + " var testMult : instance * new MyClass2()" + " var testDiv : instance / new MyClass2()" + " var testPow : instance ^ new MyClass2()" + " var testRange : instance..newMyClass2()" + " var testIn : instance in new myClass2[10]" + " }" + "" + "" + " func TestAssignFunc()" + " {" + " var instance : None MyClass2" + " instance +: new MyClass2()" + " instance -: new MyClass2()" + " instance *: new MyClass2()" + " instance ^: new MyClass2()" + " instance /: new MyClass2()" + " }" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); var boundCompilationUnit = binder.Bind(new List<CompilationUnitSyntax>() { ast }).Single(); var boundNamespace = boundCompilationUnit.Namespaces.Single(x=>x.Name== "MyNamespace"); var operatorClass = boundNamespace.Types.Single(x=>x.Name== "MyClass2"); var testClass = boundNamespace.Types.Single(x=>x.Name == "TestClass"); var testBinaryFunc = testClass.Functions.Single(x=>x.Name== "TestBinaryFunc"); var testAssignFunc = testClass.Functions.Single(x=>x.Name== "TestAssignFunc"); }
public void Test_MemberAccessExpressionBinding() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " func Add(int a, int b) -> return a * b" + " }" + "" + " class MyClass2" + " {" + " var addMethod : new MyClass().Add" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); var boundCompilationUnit = binder.Bind(new List<CompilationUnitSyntax>() { ast }).Single(); var function = boundCompilationUnit.Namespaces[0].Types.Single(x => x.Name == "MyClass") .Functions.Single(x => x.Name == "Add"); var field = boundCompilationUnit.Namespaces[0].Types.Single(x => x.Name == "MyClass2") .Fields.Single(x => x.Name == "addMethod"); Assert.That( () => field.Type, Is.InstanceOf<FunctionCompilerGeneratedType>() .And.Property("ReturnType") .InstanceOf<IntCompilerGeneratedType>()); CollectionAssert.AllItemsAreInstancesOfType( ((FunctionCompilerGeneratedType)field.Type).ParameterTypes, typeof(IntCompilerGeneratedType)); }
public void Test_TryCatch() { const string src = "namespace MyNamespace" + "{" + " class GenericClass(TypeA, TypeB)" + " {" + " Constructor(TypeA arg1, TypeB arg2)" + " {" + " Try" + " {" + " }" + " catch(Error)" + " {" + " }" + " }" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); Assert.DoesNotThrow(() => parser.Parse()); }
public void Test_primary_Constructor() { const string code = @"namespace MyNamespace" + "{" + " class MyClass" + " {" + " primary Constructor(int val)" + " {" + " }" + " }" + "}"; var parserFunc = new Action<string>( opSrc => { var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(opSrc); var parser = new Parser.Parser(tokens); parser.Parse(); }); Assert.That(() => parserFunc(code), Throws.Nothing); }
public void Test_Optional() { const string src = "namespace MyNamespace" + "{" + " class Class" + " {" + " Constructor(Optional!(int) i, Optional!(string) s)" + " {" + " }" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); Assert.DoesNotThrow(() => parser.Parse()); }
public void Test_InvalidOperatorNames_Throw() { const string template = "namespace MyNamespace" + "{{" + " class MyClass2" + " {{" + " {0}" + " }}" + "}}"; var parserFunc = new Action<string>( opSrc => { var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(string.Format(template, opSrc)); var parser = new Parser.Parser(tokens); parser.Parse(); }); Assert.That(() => parserFunc("operator Addd(MyClassName opA, MyClassName opB) -> return true"), Throws.InstanceOf<KiwiSyntaxException>().With.Message.EqualTo("Invalid operator function name 'Addd'")); }
public void Test_Infix_NamespaceLevel() { const string src = "namespace MyNamespace" + "{" + " infix func Add(int a, int b) -> return a + b" + " class MyClass2" + " {" + " func Foo()" + " {" + " var a : 1 Add 2" + " }" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var namespaceSyntax = ast.Namespaces.Single(x => x.Name.Value == "MyNamespace"); var infixFunction = namespaceSyntax.Functions.Single(x=>x.Name.Value == "Add"); Assert.IsInstanceOf<InfixFunctionSyntax>(infixFunction); }
public void Test_GenericLocalFunction_Call() { const string src = "namespace MyNamespace" + "{" + " func GenericFunction!(TypeA, TypeB)(TypeA a, TypeB b)" + " {" + " let anonFunc : func!(TypeX, TypeY)(TypeX x, TypeY y) -> return x" + " anonFunc!(a, a)" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); Assert.DoesNotThrow(() => parser.Parse()); }
public void Test_GenericFunction_NamespaceLevel() { const string src = "namespace MyNamespace" + "{" + " func GenericFunction!(TypeA, TypeB)(TypeA a, TypeB b)" + " {" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); Assert.DoesNotThrow(() => parser.Parse()); }
public void Test_IsExpression() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " func Add(int a, int b) -> return a * b" + " }" + "" + " class MyClass2" + " {" + " var myClassField : new MyClass()" + " func Foo() -> bool" + " {" + " return myClassField is MyClass" + " }" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); var boundCompilationUnit = binder.Bind(new List<CompilationUnitSyntax>() { ast }).Single(); var type = boundCompilationUnit.Namespaces[0].Types.Single(x => x.Name == "MyClass"); var function = (BoundFunction) boundCompilationUnit.Namespaces[0].Types.Single(x => x.Name == "MyClass2") .Functions.Single(x => x.Name == "Foo"); var returnStatement = (BoundReturnStatement)((BoundScopeStatement)function.Statements).Statements[0]; var boundBinaryExpression = (BoundBinaryExpression)returnStatement.Expression; Assert.AreEqual(BinaryOperators.Is, boundBinaryExpression.Operator); Assert.IsInstanceOf<BoundTypeExpression>(boundBinaryExpression.Right); Assert.AreSame(((BoundTypeExpression)boundBinaryExpression.Right).ReferencedType, type); }
public void Test_IsExpression_ThrowsTypeNotDefined() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " func Add(int a, int b) -> return a * b" + " }" + "" + " class MyClass2" + " {" + " var myClassField : new MyClass()" + " func Foo() -> bool" + " {" + " return myClassField is MyClassS" + " }" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); Assert.That( () => binder.Bind(new List<CompilationUnitSyntax>() { ast }), Throws.InstanceOf<KiwiSemanticException>().With.Message.EqualTo("MyClassS undefined Type")); }
public void Test_ValidOperatorNames_DontThrow(string opCode) { const string template = "namespace MyNamespace" + "{{" + " class MyClass2" + " {{" + " {0}" + " }}" + "}}"; var parserFunc = new Action<string>( opSrc => { var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(string.Format(template, opSrc)); var parser = new Parser.Parser(tokens); parser.Parse(); }); Assert.That(() => parserFunc(opCode), Throws.Nothing); }
public void Test_ObjectCreationExpression_ThrowsNoConstructorWithoutArguments() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " Constructor(int a){}" + " }" + " class MyClass2" + " {" + " func Foo()" + " {" + " var a : new MyClass()" + " }" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); Assert.That( () => binder.Bind(new List<CompilationUnitSyntax>() { ast }), Throws.InstanceOf<KiwiSemanticException>() .With.Message.EqualTo("MyNamespace.MyClass has no constructor without arguments.")); }
public void TestExpressions(string statementSource, Type type) { var lexer = new Lexer.Lexer(); var tokens = lexer.Lex( string.Format( NamespaceSource, string.Format( ClassSource, string.Format(FunctionSource, statementSource), string.Empty, string.Empty))); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); Assert.IsInstanceOf( type, ((ReturnStatementSyntax)((ScopeStatementSyntax)ast.Namespaces[0].Classes[0].Functions[0].Statements).Statements[0]).Expression); }
public void Test_Function_VisibilityModifiers(string code) { const string template = "namespace MyNamespace" + "{{" + " class MyClass" + " {{" + " {0}" + " }}" + "}}"; var parserFunc = new Action<string>( opSrc => { var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(string.Format(template, opSrc)); var parser = new Parser.Parser(tokens); parser.Parse(); }); Assert.That(() => parserFunc(code), Throws.Nothing); }
public void Test_IfElseExpression_IfTrueIfFalseTypeMustBeEqual() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " func Add(int a, float b) -> return if(true) a else b" + " }" + "" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); Assert.That( () => binder.Bind(new List<CompilationUnitSyntax>() { ast }), Throws.InstanceOf<KiwiSemanticException>() .With.Message.EqualTo("IfTrue and IfFalse expression Type must match")); }
public void Test_Scope_VariableNotDefined() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " func Add(int a, int b) " + " { " + " {" + " var i : 1337 + b" + " }" + " var c : a * b * i" + " }" + " }" + "" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); Assert.That( () => binder.Bind(new List<CompilationUnitSyntax>() { ast }), Throws.InstanceOf<KiwiSemanticException>().With.Message.EqualTo("i not defined")); }
public void Test_Field_without_initializer_isValid() { const string code = @"namespace MyNamespace" + "{" + " class MyClass" + " {" + " private var _some" + " primary Constructor(int val)" + " {" + " _some = val" + " }" + " }" + "}"; var parserFunc = new Action<string>( opSrc => { var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(opSrc); var parser = new Parser.Parser(tokens); parser.Parse(); }); Assert.That(() => parserFunc(code), Throws.Nothing); }
public void Test_VariableWithSameName_Throws() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " func Add(int a, int b)" + " {" + " var a : 1" + " var b : 2" + " var a : 1" + " }" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); Assert.That( () => binder.Bind(new List<CompilationUnitSyntax> { ast }), Throws.TypeOf<KiwiSemanticException>().With.Message.EqualTo("a already defined.")); }
public void Test_IfStatement_IfConditionMustBeBool() { const string src = "namespace MyNamespace" + "{" + " class MyClass" + " {" + " func Add(int a, int b) " + " { " + " if(a)" + " {" + " " + " }" + " }" + " }" + "" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); var ast = parser.Parse(); var binder = new Binder(); Assert.That( () => binder.Bind(new List<CompilationUnitSyntax>() { ast }), Throws.InstanceOf<KiwiSemanticException>().With.Message.EqualTo("If condition must be of Type Bool")); }
static void Main(string[] args) { bool interpret = false, assemble = false; string input = "", outpath = "", filename = ""; if (args.Length == 0) { Console.Error.WriteLine(helpMsg); Environment.Exit(1); } for (int i = 0; i < args.Length; i++) { string arg = args[i]; switch (arg) { case "-i": case "-interpret": { interpret = true; break; } case "-o": { outpath = args[++i]; // -o and -i can not be used together if (interpret) { Console.Error.WriteLine("-i and -o cannot be used together"); Console.Error.WriteLine(helpMsg); Environment.Exit(1); } break; } case "-a": { assemble = true; // -r and -i can not be used together if (interpret) { Console.Error.WriteLine("-i and -a cannot be used together"); Console.Error.WriteLine(helpMsg); Environment.Exit(1); } break; } default: { try { input = File.ReadAllText(arg); // This regular expression extracts the filename and discards the rest of the path and the file extension filename = Regex.Match(arg, @"^.*[\\|\/](.+?)\.[^\.]+$").Groups[1].ToString(); } catch (Exception e) when(e is FileNotFoundException || e is DirectoryNotFoundException) { Console.Error.WriteLine("File Not Found: " + arg); Environment.Exit(1); } break; } } } // if no output path given, output the file to the working dir if (outpath == "") { outpath = "."; } Stopwatch sw = new Stopwatch(); Console.WriteLine("Lexing..."); sw.Start(); var lexout = lexer.Lex(input); sw.Stop(); Console.WriteLine($"New Lex Time: {sw.ElapsedMilliseconds}ms"); sw.Reset(); Console.WriteLine("Parsing..."); var parseOut = parser.Parse(lexout); if (interpret) { Console.WriteLine("Interpreting...\n"); sw.Start(); interpreter.Interpret(parseOut); sw.Stop(); Console.WriteLine($"Interpret Time: {sw.ElapsedMilliseconds}ms"); } else { Console.WriteLine("Compiling..."); sw.Start(); var jasmin = codegen.Compile(parseOut, filename); sw.Stop(); Console.WriteLine($"Compile Time: {sw.ElapsedMilliseconds}ms"); string outFile = outpath + "/" + filename + ".j"; File.WriteAllText(outFile, jasmin); Console.WriteLine($"{outFile} created"); if (assemble) { Process p = new Process(); p.StartInfo.FileName = "java"; p.StartInfo.Arguments = $"-jar jasmin.jar {outFile}"; Console.WriteLine("Assembling..."); p.Start(); p.WaitForExit(); } } Console.WriteLine("Done!"); }
public void Test_GenericClass() { const string src = "namespace MyNamespace" + "{" + " class GenericClass(TypeA, TypeB)" + " {" + " var mutable1 : None TypeA;" + " var mutable2 : None TypeB;" + " Constructor(TypeA arg1, TypeB arg2)" + " {" + " mutable1 : arg1;" + " mutable2 : arg2;" + " }" + " }" + "}"; var lexer = new Lexer.Lexer(); var tokens = lexer.Lex(src); var parser = new Parser.Parser(tokens); Assert.DoesNotThrow(() => parser.Parse()); }