public void TestPopComparison() { var scope = new InterpreterScope(); var array = new ArrayExpression(); var funcCall = new FunctionCallExpression("happy", new ExpressionBase[] { new IntegerConstantExpression(1) }); array.Entries.Add(new ComparisonExpression(funcCall, ComparisonOperation.Equal, new IntegerConstantExpression(2))); scope.DefineVariable(new VariableDefinitionExpression("arr"), array); var happyFunc = new FunctionDefinitionExpression("happy"); happyFunc.Parameters.Add(new VariableDefinitionExpression("num1")); happyFunc.Expressions.Add(new ReturnExpression(new VariableExpression("num1"))); scope.AddFunction(happyFunc); var entry = Evaluate("array_pop(arr)", scope); Assert.That(entry, Is.InstanceOf <ComparisonExpression>()); var comparison = (ComparisonExpression)entry; Assert.That(comparison.Left, Is.InstanceOf <FunctionCallExpression>()); Assert.That(((FunctionCallExpression)comparison.Left).FunctionName.Name, Is.EqualTo("happy")); Assert.That(comparison.Right, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)comparison.Right).Value, Is.EqualTo(2)); }
internal static int LoadFunction(Script script, SourceCode source, ByteCode bytecode, bool usesGlobalEnv) { var lcontext = CreateLoadingContext(script, source); try { FunctionDefinitionExpression fnx; fnx = new FunctionDefinitionExpression(lcontext, usesGlobalEnv); int beginIp; using (bytecode.EnterSource(null)) { bytecode.Emit_Nop($"Begin function {source.Name}"); beginIp = fnx.CompileBody(bytecode, source.Name); bytecode.Emit_Nop($"End function {source.Name}"); } return(beginIp); } catch (SyntaxErrorException ex) { ex.DecorateMessage(script); ex.Rethrow(); throw; } }
public void TestReplaceVariablesIndexFunctionCall() { var input = "function func(i) => 6"; var tokenizer = new PositionalTokenizer(Tokenizer.CreateTokenizer(input)); tokenizer.Match("function"); var functionDefinition = (FunctionDefinitionExpression)FunctionDefinitionExpression.Parse(tokenizer); var functionCall = new FunctionCallExpression("func", new ExpressionBase[] { new IntegerConstantExpression(2) }); var value = new IntegerConstantExpression(98); var variable = new VariableExpression("variable"); var dict = new DictionaryExpression(); dict.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = new IntegerConstantExpression(6), Value = value }); var scope = new InterpreterScope(); scope.AssignVariable(variable, dict); scope.AddFunction(functionDefinition); var expr = new IndexedVariableExpression(variable, functionCall); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)result).Value, Is.EqualTo(98)); }
internal static int LoadFunction(Script script, SourceCode source, ByteCode bytecode, bool usesGlobalEnv) { ScriptLoadingContext lcontext = CreateLoadingContext(script, source); try { FunctionDefinitionExpression fnx; using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.AstCreation)) fnx = new FunctionDefinitionExpression(lcontext, usesGlobalEnv); int beginIp = -1; //var srcref = new SourceRef(source.SourceID); using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.Compilation)) using (bytecode.EnterSource(null)) { bytecode.Emit_Nop(string.Format("Begin function {0}", source.Name)); beginIp = fnx.CompileBody(bytecode, source.Name); bytecode.Emit_Nop(string.Format("End function {0}", source.Name)); } //Debug_DumpByteCode(bytecode, source.SourceID); return(beginIp); } catch (SyntaxErrorException ex) { ex.DecorateMessage(script); ex.Rethrow(); throw; } }
public void TestReplaceVariablesMethodCall() { var input = "function func(i) { j = i }"; var tokenizer = new PositionalTokenizer(Tokenizer.CreateTokenizer(input)); tokenizer.Match("function"); var functionDefinition = (FunctionDefinitionExpression)FunctionDefinitionExpression.Parse(tokenizer); var functionCall = new FunctionCallExpression("func", new ExpressionBase[] { new IntegerConstantExpression(2) }); var value1 = new IntegerConstantExpression(98); var expr = new DictionaryExpression(); expr.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = functionCall, Value = value1 }); var scope = new InterpreterScope(); scope.AddFunction(functionDefinition); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.False); Assert.That(result, Is.InstanceOf <ParseErrorExpression>()); Assert.That(((ParseErrorExpression)result).Message, Is.EqualTo("func did not return a value")); }
public void TestReplaceVariablesFunctionCall() { var input = "function func(i) => 6"; var tokenizer = new PositionalTokenizer(Tokenizer.CreateTokenizer(input)); tokenizer.Match("function"); var functionDefinition = (FunctionDefinitionExpression)FunctionDefinitionExpression.Parse(tokenizer); var functionCall = new FunctionCallExpression("func", new ExpressionBase[] { new IntegerConstantExpression(2) }); var value1 = new IntegerConstantExpression(98); var expr = new DictionaryExpression(); expr.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = functionCall, Value = value1 }); var scope = new InterpreterScope(); scope.AddFunction(functionDefinition); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <DictionaryExpression>()); var dictResult = (DictionaryExpression)result; Assert.That(dictResult.Entries.Count, Is.EqualTo(1)); Assert.That(dictResult.Entries[0].Key, Is.EqualTo(new IntegerConstantExpression(6))); Assert.That(dictResult.Entries[0].Value, Is.EqualTo(value1)); }
public void TestAddAndGetFunction() { var function = new FunctionDefinitionExpression("test"); var scope = new InterpreterScope(); scope.AddFunction(function); Assert.That(scope.GetFunction("test"), Is.SameAs(function)); }
private FunctionDefinitionExpression Parse(string input) { var tokenizer = new PositionalTokenizer(Tokenizer.CreateTokenizer(input)); tokenizer.Match("function"); var expr = FunctionDefinitionExpression.Parse(tokenizer); Assert.That(expr, Is.InstanceOf <FunctionDefinitionExpression>()); return((FunctionDefinitionExpression)expr); }
public void TestParseErrorInsideDefinition() { var tokenizer = new PositionalTokenizer(Tokenizer.CreateTokenizer("function func() { if (j) { j = i } }")); tokenizer.Match("function"); var expr = FunctionDefinitionExpression.Parse(tokenizer); Assert.That(expr, Is.InstanceOf <ParseErrorExpression>()); Assert.That(((ParseErrorExpression)expr).Message, Is.EqualTo("Expected conditional statement following if")); }
public void TestAppendStringNoParameters() { var expr = new FunctionDefinitionExpression("func"); var builder = new StringBuilder(); expr.AppendString(builder); Assert.That(builder.ToString(), Is.EqualTo("function func()")); // NOTE: does not output Expressions block }
protected virtual Expression VisitFunctionDefinition(FunctionDefinitionExpression node) { node.Arguments.ForEach(arg => { if (arg.HasDefault) { Visit(arg.DefaultValue); } }); Visit(node.Body); return(node); }
public FunctionDefinitionStatement(LuaParser.Stat_localfuncdefContext context, ScriptLoadingContext lcontext) : base(context, lcontext) { m_Local = true; m_FuncSymbol = lcontext.Scope.TryDefineLocal(context.NAME().GetText()); m_FuncDef = new FunctionDefinitionExpression(context.funcbody(), lcontext, context); m_SourceRef = BuildSourceRef(context.Start, context.Stop); m_FriendlyName = string.Format("{0} (local)", m_FuncSymbol.i_Name); }
public void TestGetParametersNone() { var functionDefinition = new FunctionDefinitionExpression("f"); var scope = new InterpreterScope(); var functionCall = new FunctionCallExpression("f", new ExpressionBase[0]); ExpressionBase error; var innerScope = functionCall.GetParameters(functionDefinition, scope, out error); Assert.That(innerScope, Is.Not.Null); Assert.That(error, Is.Null); Assert.That(innerScope.VariableCount, Is.EqualTo(0)); }
public FunctionDefinitionStatement(LuaParser.Stat_funcdefContext context, ScriptLoadingContext lcontext) : base(context, lcontext) { m_Local = false; var node_funcname = context.funcname(); var fnname = node_funcname.fnname; var methodaccessor = node_funcname.methodaccessor; var tableaccessor = node_funcname.funcnametableaccessor(); string nameOfMethodAccessor = methodaccessor != null ? methodaccessor.Text : null; m_TableAccessors = tableaccessor != null ? tableaccessor.Select(s => s.NAME().GetText()).ToList() : new List<string>(); m_SourceRef = BuildSourceRef(context.Start, context.Stop).SetNoBreakPoint(); m_FuncDef = new FunctionDefinitionExpression(context.funcbody(), lcontext, context, nameOfMethodAccessor != null); if (nameOfMethodAccessor != null || m_TableAccessors.Count > 0) { m_FuncSymbol = lcontext.Scope.Find(fnname.Text); m_FriendlyName = fnname.Text + "." + string.Join(".", m_TableAccessors.ToArray()); if (nameOfMethodAccessor != null) m_FriendlyName += ":" + nameOfMethodAccessor; } else { m_FuncSymbol = lcontext.Scope.Find(fnname.Text); m_FriendlyName = fnname.Text; } if (nameOfMethodAccessor != null) { m_MethodName = nameOfMethodAccessor; } else if (m_TableAccessors.Count > 0) { m_MethodName = m_TableAccessors[m_TableAccessors.Count - 1]; m_TableAccessors.RemoveAt(m_TableAccessors.Count - 1); } }
internal static int LoadFunction(Script script, SourceCode source, ByteCode bytecode, Table globalContext) { AntlrErrorListener listener = new AntlrErrorListener(source); try { LuaParser parser = CreateParser(script, new AntlrInputStream(source.Code), source.SourceID, p => p.singlefunc(), listener); ScriptLoadingContext lcontext = CreateLoadingContext(script, source); FunctionDefinitionExpression fndef; using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.AstCreation)) fndef = new FunctionDefinitionExpression(parser.anonfunctiondef(), lcontext, false, globalContext); int beginIp = -1; // var srcref = new SourceRef(source.SourceID); using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.Compilation)) using (bytecode.EnterSource(null)) { bytecode.Emit_Nop(string.Format("Begin function {0}", source.Name)); beginIp = fndef.CompileBody(bytecode, source.Name); bytecode.Emit_Nop(string.Format("End function {0}", source.Name)); Debug_DumpByteCode(bytecode, source.SourceID); } return(beginIp); } catch (ParseCanceledException ex) { HandleParserError(ex, listener); throw; } }
public void TestPopFunctionCall() { var scope = new InterpreterScope(); var array = new ArrayExpression(); array.Entries.Add(new FunctionCallExpression("happy", new ExpressionBase[] { new IntegerConstantExpression(1) })); scope.DefineVariable(new VariableDefinitionExpression("arr"), array); var happyFunc = new FunctionDefinitionExpression("happy"); happyFunc.Parameters.Add(new VariableDefinitionExpression("num1")); happyFunc.Expressions.Add(new ReturnExpression(new VariableExpression("num1"))); scope.AddFunction(happyFunc); var entry = Evaluate("array_pop(arr)", scope); // function call should not be evaluated when it's popped off the array Assert.That(entry, Is.InstanceOf <FunctionCallExpression>()); Assert.That(((FunctionCallExpression)entry).FunctionName.Name, Is.EqualTo("happy")); Assert.That(((FunctionCallExpression)entry).Parameters.Count, Is.EqualTo(1)); Assert.That(array.Entries.Count, Is.EqualTo(0)); }
private bool EvaluateFunctionDefinition(FunctionDefinitionExpression expression, InterpreterScope scope) { scope.AddFunction(expression); return(true); }
public FunctionDefinitionStatement(ScriptLoadingContext lcontext, bool local, Token localToken) : base(lcontext) { // here lexer must be at the 'function' keyword Token funcKeyword = CheckTokenType(lcontext, TokenType.Function); funcKeyword = localToken ?? funcKeyword; // for debugger purposes m_Local = local; if (m_Local) { Token name = CheckTokenType(lcontext, TokenType.Name); m_FuncSymbol = lcontext.Scope.TryDefineLocal(name.Text); m_FriendlyName = string.Format("{0} (local)", name.Text); m_SourceRef = funcKeyword.GetSourceRef(name); } else { Token name = CheckTokenType(lcontext, TokenType.Name); string firstName = name.Text; m_SourceRef = funcKeyword.GetSourceRef(name); m_FuncSymbol = lcontext.Scope.Find(firstName); m_FriendlyName = firstName; if (lcontext.Lexer.Current.Type != TokenType.Brk_Open_Round) { m_TableAccessors = new List <string>(); while (lcontext.Lexer.Current.Type != TokenType.Brk_Open_Round) { Token separator = lcontext.Lexer.Current; if (separator.Type != TokenType.Colon && separator.Type != TokenType.Dot) { UnexpectedTokenType(separator); } lcontext.Lexer.Next(); Token field = CheckTokenType(lcontext, TokenType.Name); m_FriendlyName += separator.Text + field.Text; m_SourceRef = funcKeyword.GetSourceRef(field); if (separator.Type == TokenType.Colon) { m_MethodName = field.Text; m_IsMethodCallingConvention = true; break; } else { m_TableAccessors.Add(field.Text); } } if (m_MethodName == null && m_TableAccessors.Count > 0) { m_MethodName = m_TableAccessors[m_TableAccessors.Count - 1]; m_TableAccessors.RemoveAt(m_TableAccessors.Count - 1); } } } m_FuncDef = new FunctionDefinitionExpression(lcontext, m_IsMethodCallingConvention, false); lcontext.Source.Refs.Add(m_SourceRef); }
public FunctionDefinitionStatement(ScriptLoadingContext lcontext, bool local, Token localToken) : base(lcontext) { // here lexer must be at the 'function' keyword var funcKeyword = CheckTokenType(lcontext, TokenType.Function); funcKeyword = localToken ?? funcKeyword; // for debugger purposes _local = local; if (_local) { var name = CheckTokenType(lcontext, TokenType.Name); _funcSymbol = lcontext.Scope.TryDefineLocal(name.Text); _friendlyName = $"{name.Text} (local)"; _sourceRef = funcKeyword.GetSourceRef(name); } else { var name = CheckTokenType(lcontext, TokenType.Name); string firstName = name.Text; _sourceRef = funcKeyword.GetSourceRef(name); _funcSymbol = lcontext.Scope.Find(firstName); _friendlyName = firstName; if (lcontext.Lexer.Current.Type != TokenType.Brk_Open_Round) { _tableAccessors = new List <string>(); while (lcontext.Lexer.Current.Type != TokenType.Brk_Open_Round) { var separator = lcontext.Lexer.Current; if (separator.Type != TokenType.Colon && separator.Type != TokenType.Dot) { UnexpectedTokenType(separator); } lcontext.Lexer.Next(); var field = CheckTokenType(lcontext, TokenType.Name); _friendlyName += $"{separator.Text}{field.Text}"; _sourceRef = funcKeyword.GetSourceRef(field); if (separator.Type == TokenType.Colon) { _methodName = field.Text; _isMethodCallingConvention = true; break; } _tableAccessors.Add(field.Text); } if (_methodName == null && _tableAccessors.Count > 0) { _methodName = _tableAccessors[_tableAccessors.Count - 1]; _tableAccessors.RemoveAt(_tableAccessors.Count - 1); } } } _funcDef = new FunctionDefinitionExpression(lcontext, _isMethodCallingConvention, false); lcontext.Source.Refs.Add(_sourceRef); }