/// <summary> /// 関数呼び出しの構文解析 /// </summary> /// <returns>式</returns> MExpr ParseCallExpr() { var expr = ParseSimpleExpr(); for ( ; ; ) { var pos = _tkn.Pos; if (_tkn.Type == TokenType.LP) { ReadToken(TokenType.LP); var args = ParseExprList(); ReadToken(TokenType.RP); expr = new MCallExpr(pos, expr, args); } else if (_tkn.Type == TokenType.DOT) { ReadToken(TokenType.DOT); var name = ReadStrToken(TokenType.ID); ReadToken(TokenType.LP); var args = ParseExprList(); ReadToken(TokenType.RP); expr = new MInvokeExpr(pos, expr, name, args); } else { break; } } return expr; }
/// <summary> /// 通常の関数呼び出しの型推論 /// </summary> /// <param name="fun_name">関数名</param> /// <param name="expr">式</param> static void TypeinfNormalCallExpr(MVarExpr fun_name, MCallExpr expr) { var name = fun_name.Name; if (!function_table.ContainsKey(name)) { throw new MError( string.Format("{0}: 関数 {1} は未定義です。", fun_name.Pos, name)); } var func = function_table[name]; if (expr.Args.Count != func.Args.Count) { throw new MError( string.Format("{0}: 関数 {1} のパラメータの数が不正です。", expr.Pos, name)); } for (int i = 0; i < expr.Args.Count; i++) { Unification(expr.Pos, expr.Args[i].Type, func.Args[i].Type); } expr.Type = func.RetType; }
/// <summary> /// 関数呼び出しのコンパイル /// </summary> /// <param name="ilgen">IL Generator</param> /// <param name="expr">関数呼び出し</param> static void CompileCallExpr(ILGenerator ilgen, MCallExpr expr) { foreach (var arg in expr.Args) { CompileExpr(ilgen, arg); } var method = _function_table[((MVarExpr)expr.Fun).Name]; ilgen.Emit(OpCodes.Call, method); }
/// <summary> /// 関数呼び出しの型推論 /// </summary> /// <param name="expr">関数呼び出し</param> private static void TypeinfCallExpr(MCallExpr expr) { foreach (var arg in expr.Args) { TypeinfExpr(arg); } if (expr.Fun is MVarExpr) { var fun_name = (MVarExpr)expr.Fun; TypeinfNormalCallExpr(fun_name, expr); } else { throw new NotImplementedException(); } }