private IList<KecaknoahILCode> PrecompileTry(KecaknoahTryAstNode trn, string loopId) { var id = Guid.NewGuid().ToString().Substring(0, 8); var result = new List<KecaknoahILCode>(); result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.PushCatch, StringValue = $"{id}-Catch" }); //tryブロック result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Jump, StringValue = $"{id}-Finally" }); result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"{id}-Catch" }); //catchブロック result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Jump, StringValue = $"{id}-Finally" }); result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.Label, StringValue = $"{id}-Finally" }); //finallyブロック result.AddRange(PrecompileBlock(trn.FinallyBlock.ToList(), loopId)); result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.PopCatch, StringValue = $"{id}-Catch" }); //TODO:PushCatchに番地を埋め込む対応をする return result; }
private KecaknoahTryAstNode ParseTry(Queue<KecaknoahToken> tokens) { var result = new KecaknoahTryAstNode(); tokens.SkipLogicalLineBreak(); result.AddNode(ParseBlock(tokens)); while (true) { var nt = tokens.Dequeue(); switch (nt.Type) { case KecaknoahTokenType.CatchKeyword: nt = tokens.Dequeue(); if (nt.Type != KecaknoahTokenType.Identifer) throw new KecaknoahParseException(nt.CreateErrorAt("catchブロックに変数名を指定してください。")); result.CatcherVariableName = nt.TokenString; tokens.SkipLogicalLineBreak(); result.CatcherBlock.Clear(); result.CatcherBlock = ParseBlock(tokens); break; case KecaknoahTokenType.FinallyKeyword: nt = tokens.Dequeue(); tokens.SkipLogicalLineBreak(); result.FinallyBlock.Clear(); result.FinallyBlock = ParseBlock(tokens); break; case KecaknoahTokenType.EndTryKeyword: goto EndTry; default: throw new KecaknoahParseException(nt.CreateErrorAt("不正なtry文です。")); } } EndTry: return result; }