/// <summary> /// インデクサの引数リスト処理 /// </summary> /// <param name="tokens"></param> /// <param name="parent"></param> /// <returns></returns> private KecaknoahArgumentCallExpressionAstNode ParsePrimaryIndexerAccessExpression(Queue<KecaknoahToken> tokens, KecaknoahPrimaryExpressionAstNode parent) { var r = new KecaknoahArgumentCallExpressionAstNode(); r.Target = parent; r.ExpressionType = KecaknoahOperatorType.IndexerAccess; tokens.SkipLogicalLineBreak(); //TODO: 暗黙改行 if (tokens.CheckSkipToken(KecaknoahTokenType.BracketEnd)) return r; while (true) { r.Arguments.Add(ParseExpression(tokens)); if (tokens.CheckSkipToken(KecaknoahTokenType.Comma)) continue; tokens.SkipLogicalLineBreak(); //TODO: 暗黙改行 if (tokens.CheckSkipToken(KecaknoahTokenType.BracketEnd)) break; throw new KecaknoahParseException(tokens.Peek().CreateErrorAt("メソッド呼び出しの引数リストが無効です。")); } return r; }
/// <summary> /// メンバーアクセス処理 /// </summary> /// <param name="tokens"></param> /// <param name="parent"></param> /// <returns></returns> private KecaknoahMemberAccessExpressionAstNode ParsePrimaryMemberAccessExpression(Queue<KecaknoahToken> tokens, KecaknoahPrimaryExpressionAstNode parent) { var mnt = tokens.Dequeue(); if (mnt.Type != KecaknoahTokenType.Identifer) throw new KecaknoahParseException(mnt.CreateErrorAt("有効なメンバー名を指定してください。")); var r = new KecaknoahMemberAccessExpressionAstNode(); r.Target = parent; r.ExpressionType = KecaknoahOperatorType.MemberAccess; r.MemberName = mnt.TokenString; return r; }
/// <summary> /// 一次式の処理 /// </summary> /// <param name="tokens"></param> /// <returns></returns> private KecaknoahPrimaryExpressionAstNode ParsePrimaryExpression(Queue<KecaknoahToken> tokens) { var factor = ParseFactorExpression(tokens); //tokens.SkipLogicalLineBreak(); var re = ParsePrimaryRecursiveExpression(tokens, factor); if (re != factor) return re; if (!tokens.CheckToken(KecaknoahTokenType.Increment, KecaknoahTokenType.Decrement)) return factor; re = new KecaknoahPrimaryExpressionAstNode(); re.Target = factor; if (tokens.CheckSkipToken(KecaknoahTokenType.Increment)) re.ExpressionType = KecaknoahOperatorType.Increment; if (tokens.CheckSkipToken(KecaknoahTokenType.Decrement)) re.ExpressionType = KecaknoahOperatorType.Decrement; return re; }
/// <summary> /// 再帰的に連続させられる一次式の処理 /// </summary> /// <param name="tokens"></param> /// <param name="parent"></param> /// <returns></returns> private KecaknoahPrimaryExpressionAstNode ParsePrimaryRecursiveExpression(Queue<KecaknoahToken> tokens, KecaknoahPrimaryExpressionAstNode parent) { var result = parent; if (!tokens.CheckToken(KecaknoahTokenType.Period, KecaknoahTokenType.ParenStart, KecaknoahTokenType.BracketStart)) return result; while (true) { if (tokens.CheckSkipToken(KecaknoahTokenType.Period)) { result = ParsePrimaryMemberAccessExpression(tokens, result); } else if (tokens.CheckSkipToken(KecaknoahTokenType.ParenStart)) { result = ParsePrimaryFunctionCallExpression(tokens, result); } else if (tokens.CheckSkipToken(KecaknoahTokenType.BracketStart)) { result = ParsePrimaryIndexerAccessExpression(tokens, result); } else { break; } } return result; }
internal IList<KecaknoahILCode> PrecompileSuffixIncrement(KecaknoahPrimaryExpressionAstNode node) { var result = new List<KecaknoahILCode>(); result.AddRange(PrecompileExpression(node.Target)); result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.AsValue }); result.AddRange(PrecompileExpression(node.Target)); result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.PushInteger, IntegerValue = 1 }); result.Add(new KecaknoahILCode { Type = KecaknoahILCodeType.PlusAssign }); return result; }