private Parser <Value> GetAssignmentParser(Scope.Builder scopeBuilder, ErrorContext errorContext) { var assignmentParser = from variableDefinition in GetVariableDefinitionParser(scopeBuilder, errorContext) from assignmentOperator in Parse.Char('=').Token() from value in _mainParser select GetAssignmentExpression(scopeBuilder, variableDefinition.Name, value, variableDefinition.Mutable); return(assignmentParser); }
private Parser <Value> GetVariableParser(Scope.Builder scopeBuilder, ErrorContext errorContext) { var variableParser = from variableDefinition in GetVariableDefinitionParser(scopeBuilder, errorContext) select variableDefinition.Index.Type == Types.error ? default(Value) : AllocateExpression(Types.Any, new[] { Instruction.ReadVariable(variableDefinition.Index) }); return(variableParser); }
private Value GetAssignmentExpression(Scope.Builder scopeBuilder, string variableName, Value valueExpression, bool mutable) { if (valueExpression.Type == Types.error) { return(valueExpression); } var instructions = new List <Instruction>(); var expression = Heap.GetExpression((int)valueExpression.Raw); instructions.AddRange(expression.Instructions); instructions.Add(Instruction.AssignVariable(scopeBuilder.GetOrCreateIndex(variableName), mutable)); valueExpression.RemoveRef(); return(AllocateExpression(expression.Type, instructions.ToArray())); }
private Value GetVariableIndex(string variableName, Scope.Builder scopeBuilder, ErrorContext errorContext) { int index; if (!scopeBuilder.TryGetIndex(variableName, out index)) { var message = $"Unknown variable: '{variableName}'."; if (errorContext.IsEmpty || errorContext.Peek().Message != message) { errorContext.AddError(new Error(message)); } return(default(Value)); } return(new Value(index)); }
private Parser <VariableDefinition> GetVariableDefinitionParser(Scope.Builder scopeBuilder, ErrorContext errorContext) { var variableDefinitionParser = from mutableMarker in Parse.Char('$').Once().Optional() from first in Parse.Letter.Once() from rest in Parse.LetterOrDigit.Or(Parse.Chars('_', '-')).Many() let name = new string( mutableMarker.GetOrElse(Enumerable.Empty <char>()) .Concat(first) .Concat(rest).ToArray()) select new VariableDefinition { Index = GetVariableIndex(name, scopeBuilder, errorContext), Name = name, Mutable = mutableMarker.IsDefined }; return(variableDefinitionParser); }
private Parser <Value> GetLiteralExpressionParser(Scope.Builder scopeBuilder, ErrorContext errorContext) { var booleanParser = GetBooleanLiteralParser(); var integerParser = GetIntegerLiteralParser(); var floatParser = GetFloatLiteralParser(); var typeParser = GetTypeLiteralParser(); var stringParser = GetStringLiteralParser(); var tupleParser = GetTupleLiteralParser(); var listParser = GetListLiteralParser(); var variableParser = GetVariableParser(scopeBuilder, errorContext); var literalParser = booleanParser .Or(floatParser) .Or(integerParser) .Or(typeParser) .Or(stringParser) .Or(tupleParser) .Or(listParser) .Or(variableParser); return(literalParser); }
public GarplyParser(ErrorContext errorContext, Scope.Builder scopeBuilder) { Parser <Value> mainParser = null; _mainParser = Parse.Ref(() => mainParser); _errorContext = errorContext; var expressionLiteralParser = GetExpressionLiteralParser(); var expressionParser = GetExprParser(); var evalParser = GetEvalParser(); var assignmentParser = GetAssignmentParser(scopeBuilder, errorContext); var literalParser = GetLiteralExpressionParser(scopeBuilder, errorContext); mainParser = expressionLiteralParser.Or( expressionParser).Or( evalParser).Or( assignmentParser).Or( literalParser) .Token(); _tryParse = mainParser.TryParse; }