public ForExpression(VariableDefinitionExpression iteratorName, ExpressionBase range) : base(ExpressionType.For) { IteratorName = iteratorName; Range = range; Expressions = new List <ExpressionBase>(); }
/// <summary> /// Updates the value of a variable. /// </summary> /// <param name="variable">The variable.</param> /// <param name="value">The value.</param> public ParseErrorExpression AssignVariable(VariableExpression variable, ExpressionBase value) { var indexedVariable = variable as IndexedVariableExpression; if (indexedVariable != null) { return(indexedVariable.Assign(this, value)); } var variableDefinition = new VariableDefinitionExpression(variable); // find the scope where the variable is defined and update it there. foreach (var scope in VisibleScopes) { if (scope._variables != null && scope._variables.ContainsKey(variable.Name)) { scope._variables[variable.Name] = new VariableDefinitionPair(variableDefinition, value); return(null); } if (scope._variable.Key != null && scope._variable.Key.Name == variable.Name) { scope._variable = new VariableDefinitionPair(variableDefinition, value); return(null); } } // variable not defined, store in the current scope. DefineVariable(variableDefinition, value); return(null); }
protected FunctionDefinitionExpression(VariableDefinitionExpression name) : base(ExpressionType.FunctionDefinition) { Name = name; Parameters = new List <VariableDefinitionExpression>(); Expressions = new List <ExpressionBase>(); DefaultParameters = new TinyDictionary <string, ExpressionBase>(); }
/// <summary> /// Parses a for loop. /// </summary> /// <remarks> /// Assumes the 'for' keyword has already been consumed. /// </remarks> internal static ExpressionBase Parse(PositionalTokenizer tokenizer, int line = 0, int column = 0) { ExpressionBase.SkipWhitespace(tokenizer); var keywordFor = new KeywordExpression("for", line, column); line = tokenizer.Line; column = tokenizer.Column; var iteratorName = tokenizer.ReadIdentifier(); if (iteratorName.IsEmpty) { return(ParseError(tokenizer, "Invalid function name", line, column)); } var iterator = new VariableDefinitionExpression(iteratorName.ToString(), line, column); ExpressionBase.SkipWhitespace(tokenizer); line = tokenizer.Line; column = tokenizer.Column; if (!tokenizer.Match("in")) { return(ParseError(tokenizer, "Expected 'in' after loop variable")); } var keywordIn = new KeywordExpression("in", line, column); var range = ExpressionBase.Parse(tokenizer); if (range.Type == ExpressionType.ParseError) { return(range); } var loop = new ForExpression(iterator, range); var error = ExpressionBase.ParseStatementBlock(tokenizer, loop.Expressions); if (error != null) { return(error); } loop._keywordFor = keywordFor; loop._keywordIn = keywordIn; loop.Line = keywordFor.Line; loop.Column = keywordFor.Column; loop.EndLine = tokenizer.Line; loop.EndColumn = tokenizer.Column; return(loop); }
/// <summary> /// Assigns the value to a variable for the current scope. /// </summary> /// <param name="variable">The variable.</param> /// <param name="value">The value.</param> public void DefineVariable(VariableDefinitionExpression variable, ExpressionBase value) { if (_variables == null) { if (_variable.Key == null) { _variable = new VariableDefinitionPair(variable, value); return; } _variables = new Dictionary <string, VariableDefinitionPair>(); _variables.Add(_variable.Key.Name, _variable); _variable = new VariableDefinitionPair(); } _variables[variable.Name] = new VariableDefinitionPair(variable, value); }
/// <summary> /// Parses a function definition. /// </summary> /// <remarks> /// Assumes the 'function' keyword has already been consumed. /// </remarks> internal static ExpressionBase Parse(PositionalTokenizer tokenizer, int line = 0, int column = 0) { var locationStart = new TextLocation(line, column); // location of 'function' keyword ExpressionBase.SkipWhitespace(tokenizer); line = tokenizer.Line; column = tokenizer.Column; var functionName = tokenizer.ReadIdentifier(); var functionNameVariable = new VariableDefinitionExpression(functionName.ToString(), line, column); var function = new UserFunctionDefinitionExpression(functionNameVariable); function.Location = new TextRange(locationStart.Line, locationStart.Column, 0, 0); if (functionName.IsEmpty) { return(ExpressionBase.ParseError(tokenizer, "Invalid function name")); } return(function.Parse(tokenizer)); }
public VariableReferenceExpression(VariableDefinitionExpression variable, ExpressionBase expression) : base(ExpressionType.VariableReference) { Variable = variable; Expression = expression; }
/// <summary> /// Assigns the value to a variable for the current scope. /// </summary> /// <param name="variable">The variable.</param> /// <param name="value">The value.</param> public void DefineVariable(VariableDefinitionExpression variable, ExpressionBase value) { _variables[variable.Name] = new KeyValuePair <VariableDefinitionExpression, ExpressionBase>(variable, value); }
protected AnonymousUserFunctionDefinitionExpression(VariableDefinitionExpression name) : base(name) { CapturedVariables = Enumerable.Empty <VariableReferenceExpression>(); }
protected new ExpressionBase Parse(PositionalTokenizer tokenizer) { ExpressionBase.SkipWhitespace(tokenizer); if (tokenizer.NextChar != '(') { return(ExpressionBase.ParseError(tokenizer, "Expected '(' after function name", Name)); } tokenizer.Advance(); ExpressionBase.SkipWhitespace(tokenizer); if (tokenizer.NextChar != ')') { do { var line = tokenizer.Line; var column = tokenizer.Column; var parameter = tokenizer.ReadIdentifier(); if (parameter.IsEmpty) { return(ExpressionBase.ParseError(tokenizer, "Invalid parameter name", line, column)); } var variableDefinition = new VariableDefinitionExpression(parameter.ToString(), line, column); Parameters.Add(variableDefinition); ExpressionBase.SkipWhitespace(tokenizer); if (tokenizer.NextChar == '=') { tokenizer.Advance(); ExpressionBase.SkipWhitespace(tokenizer); var value = ExpressionBase.Parse(tokenizer); if (value.Type == ExpressionType.ParseError) { return(ExpressionBase.ParseError(tokenizer, "Invalid default value for " + parameter.ToString(), value)); } var scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope()); scope.Context = new TriggerBuilderContext(); // prevent errors passing memory references as default parameters ExpressionBase evaluated; if (!value.ReplaceVariables(scope, out evaluated)) { return(ExpressionBase.ParseError(tokenizer, "Default value for " + parameter.ToString() + " is not constant", evaluated)); } DefaultParameters[parameter.ToString()] = evaluated; } else if (DefaultParameters.Count > 0) { return(ExpressionBase.ParseError(tokenizer, string.Format("Non-default parameter {0} appears after default parameters", parameter.ToString()), variableDefinition)); } if (tokenizer.NextChar == ')') { break; } if (tokenizer.NextChar != ',') { return(ExpressionBase.ParseError(tokenizer, "Expected ',' or ')' after parameter name, found: " + tokenizer.NextChar)); } tokenizer.Advance(); ExpressionBase.SkipWhitespace(tokenizer); } while (true); } tokenizer.Advance(); // closing parenthesis ExpressionBase.SkipWhitespace(tokenizer); ExpressionBase expression; if (tokenizer.Match("=>")) { return(ParseShorthandBody(tokenizer)); } if (tokenizer.NextChar != '{') { return(ExpressionBase.ParseError(tokenizer, "Expected '{' after function declaration", Name)); } tokenizer.Advance(); ExpressionBase.SkipWhitespace(tokenizer); bool seenReturn = false; while (tokenizer.NextChar != '}') { expression = ExpressionBase.Parse(tokenizer); if (expression.Type == ExpressionType.ParseError) { // the ExpressionTokenizer will capture the error, we should still return the incomplete FunctionDefinition if (tokenizer is ExpressionTokenizer) { break; } // not an ExpressionTokenizer, just return the error return(expression); } if (expression.Type == ExpressionType.Return) { seenReturn = true; } else if (seenReturn) { ExpressionBase.ParseError(tokenizer, "Expression after return statement", expression); } Expressions.Add(expression); ExpressionBase.SkipWhitespace(tokenizer); } Location = new TextRange(Location.Start, tokenizer.Location); tokenizer.Advance(); return(MakeReadOnly(this)); }
protected UserFunctionDefinitionExpression(VariableDefinitionExpression name) : base(name) { }
public FunctionDefinitionExpression(string name) : this() { Name = new VariableDefinitionExpression(name); }