ControlNode GetControlNode(IList <Token> tokens, ref int index) { ControlNode controlNode; Token token = tokens[index++]; int count = tokens.Count; switch (token.Type) { case TokenType.FI: controlNode = new FiNode(); break; case TokenType.FAL: controlNode = new FalNode(); break; default: throw new ApplicationException($"Invalid token: {tokens}"); } if (index >= count) { throw new ApplicationException("End of code in fi syntax"); } controlNode.CompareExpression = GetCompareNode(tokens, ref index); if (controlNode.CompareExpression == null) { throw new ApplicationException("Not found compare expression"); } token = tokens[index]; if (token.Type != TokenType.RINYV) { throw new ApplicationException($"Not found 'rinyv': fi {controlNode.CompareExpression}"); } index++; controlNode.Syntaxes = GetSyntaxNode(tokens, ref index); token = tokens[index]; if (token.Type != TokenType.SITUV) { throw new ApplicationException($"Not found 'situv': fi {controlNode.CompareExpression}"); } index++; return(controlNode); }
protected override void ToFal(FalNode node, IDictionary <IdentifierNode, uint> anaxDictionary) { // 内部で使用する変数領域の確保 var anaxList = node.Syntaxes.Where(x => x is AnaxNode) .Select(x => (x as AnaxNode)).ToList(); int stackCount = anaxList.Select(x => int.Parse(x.Length.Value)).Sum(); int block = this.blockCount++; this.writer.WriteLine("nta {0} f5 ; allocate variables in fal", stackCount * 4); // 条件式 this.writer.WriteLine("nll --fal-rinyv-{0}--", block); OutputExpression(node.CompareExpression, "f0", anaxDictionary); this.writer.WriteLine("fi f0 0 clo malkrz --fal-situv-{0}-- xx ; rinyv fal", block); int count = 0; for (int i = 0; i < anaxList.Count; i++) { AnaxNode anax = anaxList[i]; if (anaxDictionary.ContainsKey(anax.Name)) { throw new ApplicationException($"Duplication variable name: {anax.Name} in fal"); } count += int.Parse(anax.Length.Value); anaxDictionary.Add(anax.Name, (uint)(-(this.cersvaStackCount + count) * 4)); ToAnax(anax, anaxDictionary); } // 文の処理 OutputSyntax(node.Syntaxes, anaxDictionary); // 内部で使用した変数領域の解放 foreach (var anax in anaxList) { anaxDictionary.Remove(anax.Name); } this.writer.WriteLine("krz --fal-rinyv-{0}-- xx", block); this.writer.WriteLine("nll --fal-situv-{0}-- ata {1} f5 ; situv fal", block, stackCount * 4); }
protected abstract void ToFal(FalNode node, IDictionary <IdentifierNode, uint> anaxDictionary);