public ActionResult <Result> Post([FromBody] Dto dto) { if (dto == null || string.IsNullOrEmpty(dto.Text)) { return(BadRequest()); } string add = dto.Text.Last().Equals('\n') ? " " : "\n"; OuterLexemes lex = _manager.LexicalAnalyzer(dto.Text + add); SyntaxResult syn = _manager.SyntaxAnalyzer(lex); if (!syn.Success) { return(new Result { OuterLexemes = lex, SyntaxResult = syn, ReferenceNumber = Guid.NewGuid() }); } PolishResult polishResult = _polishManager.Run(lex); Guid referenceNumber = Guid.NewGuid(); _cache.Set(referenceNumber, new ExecutionPoint { PolishResult = polishResult }); return(new Result { OuterLexemes = lex, SyntaxResult = syn, // todo Use AutoMapper PolishResult = new PolishResultDto { ReversePolishNotation = string.Join(" ", polishResult.ReversePolishNotation.Select(pn => pn.Token)), Trace = polishResult.Trace.Select(t => new PolishTraceDto { Input = t.Input, Stack = string.Join(" | ", t.Stack.Select(pn => pn.Token)), ReversePolishNotation = string.Join(" ", t.ReversePolishNotation.Select(pn => pn.Token)) }) }, ReferenceNumber = referenceNumber }); }
public ExecutionResult Run( PolishResult polishResult, ExecutionPoint executionPoint = default, decimal input = default) { var outputBuilder = new StringBuilder(); _stack.Clear(); _declaredIdentifiers.Clear(); _identifiersValues.Clear(); int i = 0; if (executionPoint != default) { _stack = executionPoint.Stack; _declaredIdentifiers = executionPoint.DeclaredIdentifiers; _identifiersValues = executionPoint.IdentifiersValues; i = executionPoint.PolishNotationIndex; _stack.Push(input.ToString(CultureInfo.InvariantCulture)); HandleSet(); } try { while (i < polishResult.ReversePolishNotation.Count) { PolishNotation element = polishResult.ReversePolishNotation[i]; switch (element.Type) { case PolishNotationTokenType.Identifier: _stack.Push(_identifiersValues.ContainsKey(element.Token) && !element.IsAssignmentToThisIdentifier ? _identifiersValues[element.Token].ToString(CultureInfo.InvariantCulture) : element.Token); // only for declaration or assignment break; case PolishNotationTokenType.Literal: _stack.Push(element.Token); break; case PolishNotationTokenType.Operator: switch (element.Token) { case "@+": case "@-": HandleArithmeticUnary(element); break; case "+": case "-": case "*": case "/": HandleArithmeticBinary(element); break; case "var": HandleVar(); break; case "set": HandleSet(); break; case "write": string head = _stack.Pop(); if (head.StartsWith("@")) { throw new RuntimeException($"{head} is not declared"); } outputBuilder.AppendLine(head.ToString(CultureInfo.InvariantCulture)); break; case "read": return(new ExecutionResult { Type = ExecutionResultType.InputRequired, Output = outputBuilder.ToString(), ExecutionPoint = new ExecutionPoint { PolishNotationIndex = i + 1, Stack = _stack, DeclaredIdentifiers = _declaredIdentifiers, IdentifiersValues = _identifiersValues, PolishResult = polishResult } }); case "equals": case "greaterthn": case "lessthn": HandleConditional(element); break; } break; case PolishNotationTokenType.Delimiter: break; case PolishNotationTokenType.If: break; case PolishNotationTokenType.Then: break; case PolishNotationTokenType.Fi: break; case PolishNotationTokenType.While: break; case PolishNotationTokenType.TechnicalDo: break; case PolishNotationTokenType.Enddo: break; case PolishNotationTokenType.Label: PolishNotation nextElement = polishResult.ReversePolishNotation[i + 1]; switch (nextElement.Token) { case "УПХ": bool operand = Convert.ToBoolean(_stack.Pop()); if (!operand) { i = polishResult.LabelAddresses[element.Token]; continue; } break; case "БП": i = polishResult.LabelAddresses[element.Token]; continue; } break; default: throw new ArgumentOutOfRangeException(); } i++; } } catch (RuntimeException e) { outputBuilder.AppendLine(e.Message); } return(new ExecutionResult { Type = ExecutionResultType.Completed, Output = outputBuilder.ToString() }); }