From 3588eaaf96066e66449b6ae7f0f085c84592d04e Mon Sep 17 00:00:00 2001 From: fawdlstty Date: Wed, 22 Dec 2021 19:06:31 +0800 Subject: [PATCH] 0.0.5 complete built-in methods --- fa/fac.Test/BuildTool.cs | 1 + fa/fac.Test/UnitTest00_hello.cs | 47 +++++++++++ fa/fac/ASTs/Exprs/AstExpr_AccessBuildIn.cs | 2 +- fa/fac/ASTs/Exprs/AstExpr_BaseId.cs | 2 +- fa/fac/ASTs/Exprs/AstExpr_OpN.cs | 2 + .../ASTs/Exprs/Names/AstExprName_BuildIn.cs | 58 ++++++++------ fa/fac/ASTs/Structs/AstClass.cs | 1 + fa/fac/ASTs/Structs/AstEnum.cs | 1 + fa/fac/ASTs/Structs/AstTemplateClassInst.cs | 1 + fa/fac/ASTs/Structs/AstTemplateEnumInst.cs | 1 + fa/fac/AntlrTools/ExprTraversals.cs | 5 +- fa/fac/Info.cs | 8 +- fa/fac/Program.cs | 78 ++++++++++--------- fa/fac/fa/Error.fa | 6 ++ fa/fac/fa/Optional.fa | 6 ++ fa/fac/fac.csproj | 20 ++++- test/App.fa | 12 +-- 17 files changed, 171 insertions(+), 80 deletions(-) create mode 100644 fa/fac/fa/Error.fa create mode 100644 fa/fac/fa/Optional.fa diff --git a/fa/fac.Test/BuildTool.cs b/fa/fac.Test/BuildTool.cs index 029f6e8..1bfa2e0 100644 --- a/fa/fac.Test/BuildTool.cs +++ b/fa/fac.Test/BuildTool.cs @@ -62,6 +62,7 @@ private static string _RunAndGetReturn (string _code) { // // 璇诲彇婧愮爜 Info.CurrentFile = Path.Combine (Info.SrcPath, "App.fa"); + File.WriteAllText (Info.CurrentFile, _code); Log.Mark (LogMark.Parse); Info.Programs.Clear (); Info.Programs.Add (Common.ParseCode (Info.CurrentSourceCode = _code)); diff --git a/fa/fac.Test/UnitTest00_hello.cs b/fa/fac.Test/UnitTest00_hello.cs index 5540a65..c4cfb35 100644 --- a/fa/fac.Test/UnitTest00_hello.cs +++ b/fa/fac.Test/UnitTest00_hello.cs @@ -17,5 +17,52 @@ public static void Main () { string _ret = BuildTool.RunAndGetReturn (_code); Assert.AreEqual (_ret, "hello"); } + + [TestMethod] + public void TestMethod2 () { + // 备注:所有内建方法请参见 fa/fac/ASTs/Exprs/Names/AstExprName_BuildIn.cs + string _code = @" +use fa; + +class Program { + public static void Main () { + // 读当前文件 + string _src1 = File.ReadAllText (@FILE); + // 直接获取当前文件源码 + string _src2 = @FILEDATA; + if _src1 != _src2 { + Console.WriteLine (""error""); + } + // 控制台输出/控制台输出行 + Console.Write (""a""); + Console.WriteLine (""b""); + // 检查文件是否存在 + if !File.Exists (@FILE) { + Console.WriteLine (""error""); + } + // 写文件 + File.WriteAllText (""D:\\a.fa"", ""// this file generate by fa test\r\n""); + // 追加文件 + File.AppendAllText (""D:\\a.fa"", @FILEDATA); + // 输出文件大小 + string _src3 = File.ReadAllText (""D:\\a.fa""); + Console.Write (""{0}"".Format (_src3.Length)); + // 删除临时文件 + File.Delete (""D:\\a.fa""); + //// 判断文件夹是否存在 + //bool _b = Directory.Exists (""D:\\folder""); + //// 创建文件夹 + //Directory.Create (""D:\\folder""); + //// 获取文件夹下所有文件名称 + //string[] _files = Directory.GetFiles (""D:\\folder""); + //// 删除文件夹 + //Directory.Delete (""D:\\folder""); + } +} +"; + string _ret = BuildTool.RunAndGetReturn (_code); + Assert.AreEqual (_ret[..4], "ab\r\n"); + Assert.IsTrue (int.Parse (_ret[4..]) > 500); + } } } diff --git a/fa/fac/ASTs/Exprs/AstExpr_AccessBuildIn.cs b/fa/fac/ASTs/Exprs/AstExpr_AccessBuildIn.cs index 0a8a021..1665641 100644 --- a/fa/fac/ASTs/Exprs/AstExpr_AccessBuildIn.cs +++ b/fa/fac/ASTs/Exprs/AstExpr_AccessBuildIn.cs @@ -227,7 +227,7 @@ public override string GenerateCSharp (int _indent) { var _attach0 = (AttachArgs?.Count ?? 0) > 0 ? AttachArgs[0].GenerateCSharp (_indent) : ""; return AccessType switch { AccessBuildInType.ARR_New => $"new {_exp} ()", - AccessBuildInType.ARR_Length => $"{_b}.Count", + AccessBuildInType.ARR_Length => Value.ExpectType is AstType_ArrayWrap ? $"{_b}.Count" : $"{_b}.Length", AccessBuildInType.ARR_Add => $"{_b}.Add ({_attach0})", AccessBuildInType.ARR_AccessItem => $"{_b} [{_attach0}]", AccessBuildInType.OPT_HasValue => $"{_b}.HasValue ()", diff --git a/fa/fac/ASTs/Exprs/AstExpr_BaseId.cs b/fa/fac/ASTs/Exprs/AstExpr_BaseId.cs index 91ab72a..f6c2d72 100644 --- a/fa/fac/ASTs/Exprs/AstExpr_BaseId.cs +++ b/fa/fac/ASTs/Exprs/AstExpr_BaseId.cs @@ -27,7 +27,7 @@ public override IAstExpr TraversalCalcType (IAstType _expect_type) { ExprTraversals.Complete = false; return this; } else { - throw new Exception ("鎵ц绫诲瀷澶勭悊姝ラ鏃朵笉鍐嶅厑璁稿嚭鐜 AstExpr_BaseId 绫诲瀷瀵硅薄"); + throw new CodeException (Token, $"鏈畾涔夌殑鏍囪瘑绗 {Id}"); } } diff --git a/fa/fac/ASTs/Exprs/AstExpr_OpN.cs b/fa/fac/ASTs/Exprs/AstExpr_OpN.cs index 90e3a23..6d2ea3a 100644 --- a/fa/fac/ASTs/Exprs/AstExpr_OpN.cs +++ b/fa/fac/ASTs/Exprs/AstExpr_OpN.cs @@ -138,6 +138,8 @@ public override string GenerateCSharp (int _indent) { if (Arguments.Any ()) _sb.Remove (_sb.Length - 2, 2); _sb.Append (")"); + if (Value is AstExprName_BuildIn _biexpr1 && _biexpr1.Name == "Directory.GetFiles") + _sb.Append (".ToList ()"); return _sb.ToString (); } diff --git a/fa/fac/ASTs/Exprs/Names/AstExprName_BuildIn.cs b/fa/fac/ASTs/Exprs/Names/AstExprName_BuildIn.cs index 005d27d..6c93873 100644 --- a/fa/fac/ASTs/Exprs/Names/AstExprName_BuildIn.cs +++ b/fa/fac/ASTs/Exprs/Names/AstExprName_BuildIn.cs @@ -1,4 +1,5 @@ -锘縰sing fac.ASTs.Types; +锘縰sing fac.ASTs.Stmts; +using fac.ASTs.Types; using fac.Exceptions; using System; using System.Collections.Generic; @@ -15,17 +16,27 @@ public class AstExprName_BuildIn: IAstExprName { private static Dictionary sBuildIn = new Dictionary { - ["continue"] = new AstExprName_BuildIn { Token = null, Name = "continue", NameType = "void" }, - ["break"] = new AstExprName_BuildIn { Token = null, Name = "break", NameType = "void" }, - ["Console.WriteLine"] = new AstExprName_BuildIn { Token = null, Name = "Console.WriteLine", NameType = "Func" }, - ["Console.Write"] = new AstExprName_BuildIn { Token = null, Name = "Console.Write", NameType = "Func" }, - ["string.Format"] = new AstExprName_BuildIn { Token = null, Name = "string.Format", NameType = "Func" }, - ["File.Exists"] = new AstExprName_BuildIn { Token = null, Name = "File.Exists", NameType = "Func" }, - ["File.ReadAllText"] = new AstExprName_BuildIn { Token = null, Name = "File.ReadAllText", NameType = "Func" }, - ["File.WriteAllText"] = new AstExprName_BuildIn { Token = null, Name = "File.WriteAllText", NameType = "Func" }, - ["File.AppendAllText"] = new AstExprName_BuildIn { Token = null, Name = "File.AppendAllText", NameType = "Func" }, - ["@FILE"] = new AstExprName_BuildIn { Token = null, Name = "@FILE", NameType = "string" }, - ["@SOURCE"] = new AstExprName_BuildIn { Token = null, Name = "@SOURCE", NameType = "string" }, + ["continue"] = new AstExprName_BuildIn { Name = "continue", NameType = "void" }, + ["break"] = new AstExprName_BuildIn { Name = "break", NameType = "void" }, + // + ["Console.WriteLine"] = new AstExprName_BuildIn { Name = "Console.WriteLine", NameType = "Func" }, + ["Console.Write"] = new AstExprName_BuildIn { Name = "Console.Write", NameType = "Func" }, + // + ["string.Format"] = new AstExprName_BuildIn { Name = "string.Format", NameType = "Func" }, + // + ["File.Exists"] = new AstExprName_BuildIn { Name = "File.Exists", NameType = "Func" }, + ["File.ReadAllText"] = new AstExprName_BuildIn { Name = "File.ReadAllText", NameType = "Func" }, + ["File.WriteAllText"] = new AstExprName_BuildIn { Name = "File.WriteAllText", NameType = "Func" }, + ["File.AppendAllText"] = new AstExprName_BuildIn { Name = "File.AppendAllText", NameType = "Func" }, + ["File.Delete"] = new AstExprName_BuildIn { Name = "File.Delete", NameType = "Func" }, + // + ["Directory.Exists"] = new AstExprName_BuildIn { Name = "Directory.Exists", NameType = "Func" }, + ["Directory.Create"] = new AstExprName_BuildIn { Name = "Directory.Create", NameType = "Func" }, + ["Directory.Delete"] = new AstExprName_BuildIn { Name = "Directory.Delete", NameType = "Func" }, + ["Directory.GetFiles"] = new AstExprName_BuildIn { Name = "Directory.GetFiles", NameType = "Func" }, + // + ["@FILE"] = new AstExprName_BuildIn { Name = "@FILE", NameType = "string" }, + ["@FILEDATA"] = new AstExprName_BuildIn { Name = "@FILEDATA", NameType = "string" }, }; public static AstExprName_BuildIn FindFromName (string _name) { @@ -36,29 +47,26 @@ public static AstExprName_BuildIn FindFromName (string _name) { public override IAstExpr TraversalCalcType (IAstType _expect_type) { if (ExpectType == null) - ExpectType = NameType != "" ? IAstType.FromName (NameType) : null; + ExpectType = IAstType.FromName (NameType); return AstExprTypeCast.Make (this, _expect_type); } public override IAstType GuessType () { if (ExpectType == null) - ExpectType = NameType != "" ? IAstType.FromName (NameType) : null; + ExpectType = IAstType.FromName (NameType); return ExpectType; } + public override (List, IAstExpr) ExpandExpr ((IAstExprName _var, AstStmt_Label _pos)? _cache_err) { + // TODO 鎵╁睍鍐欐枃浠朵箣绫荤殑閿欒鍒ゆ柇 + return (new List (), this); + } + public override string GenerateCSharp (int _indent) => Name switch { - "continue" => "continue", - "break" => "break", - "Console.WriteLine" => "Console.WriteLine", - "Console.Write" => "Console.Write", - "string.Format" => "string.Format", - "File.Exists" => "File.Exists", - "File.ReadAllText" => "File.ReadAllText", - "File.WriteAllText" => "File.WriteAllText", - "File.AppendAllText" => "File.AppendAllText", + "Directory.Create" => "Directory.CreateDirectory", "@FILE" => Common.WrapStringValue (Info.CurrentFile), - "@SOURCE" => Common.WrapStringValue (File.ReadAllText (Info.CurrentFile, Encoding.UTF8)), - _ => throw new UnimplException (Token), + "@FILEDATA" => Common.WrapStringValue (File.ReadAllText (Info.CurrentFile, Encoding.UTF8)), + _ => Name, }; public override bool AllowAssign () => false; diff --git a/fa/fac/ASTs/Structs/AstClass.cs b/fa/fac/ASTs/Structs/AstClass.cs index 6e66629..e0674bf 100644 --- a/fa/fac/ASTs/Structs/AstClass.cs +++ b/fa/fac/ASTs/Structs/AstClass.cs @@ -72,6 +72,7 @@ public bool Compile () { ClassFuncs[j].BodyCodes.TraversalWraps ((_deep: 1, _group: 0, _loop: 0, _cb: ExprTraversals.Traversal)); Info.InitFunc (ClassFuncs[j]); ClassFuncs[j].BodyCodes.TraversalWraps ((_deep: 1, _group: 0, _loop: 1, _cb: ExprTraversals.Traversal)); + ClassFuncs[j].BodyCodes.TraversalCalcType (); Info.InitFunc (ClassFuncs[j]); ClassFuncs[j].BodyCodes.TraversalWraps ((_deep: 1, _group: 0, _loop: i, _cb: ExprTraversals.Traversal)); } diff --git a/fa/fac/ASTs/Structs/AstEnum.cs b/fa/fac/ASTs/Structs/AstEnum.cs index 395f7e3..086e070 100644 --- a/fa/fac/ASTs/Structs/AstEnum.cs +++ b/fa/fac/ASTs/Structs/AstEnum.cs @@ -103,6 +103,7 @@ public bool Compile () { ClassFuncs[j].BodyCodes.TraversalWraps ((_deep: 1, _group: 0, _loop: 0, _cb: ExprTraversals.Traversal)); Info.InitFunc (ClassFuncs[j]); ClassFuncs[j].BodyCodes.TraversalWraps ((_deep: 1, _group: 0, _loop: 1, _cb: ExprTraversals.Traversal)); + ClassFuncs[j].BodyCodes.TraversalCalcType (); Info.InitFunc (ClassFuncs[j]); ClassFuncs[j].BodyCodes.TraversalWraps ((_deep: 1, _group: 0, _loop: i, _cb: ExprTraversals.Traversal)); } diff --git a/fa/fac/ASTs/Structs/AstTemplateClassInst.cs b/fa/fac/ASTs/Structs/AstTemplateClassInst.cs index 3d4ac96..1555df5 100644 --- a/fa/fac/ASTs/Structs/AstTemplateClassInst.cs +++ b/fa/fac/ASTs/Structs/AstTemplateClassInst.cs @@ -93,6 +93,7 @@ public bool Compile () { ClassFuncs[j].BodyCodes.TraversalWraps ((_deep: 1, _group: 0, _loop: 0, _cb: ExprTraversals.Traversal)); Info.InitFunc (ClassFuncs[j]); ClassFuncs[j].BodyCodes.TraversalWraps ((_deep: 1, _group: 0, _loop: 1, _cb: ExprTraversals.Traversal)); + ClassFuncs[j].BodyCodes.TraversalCalcType (); Info.InitFunc (ClassFuncs[j]); ClassFuncs[j].BodyCodes.TraversalWraps ((_deep: 1, _group: 0, _loop: i, _cb: ExprTraversals.Traversal)); } diff --git a/fa/fac/ASTs/Structs/AstTemplateEnumInst.cs b/fa/fac/ASTs/Structs/AstTemplateEnumInst.cs index 2005c72..1c6ae27 100644 --- a/fa/fac/ASTs/Structs/AstTemplateEnumInst.cs +++ b/fa/fac/ASTs/Structs/AstTemplateEnumInst.cs @@ -116,6 +116,7 @@ public bool Compile () { ClassFuncs[j].BodyCodes.TraversalWraps ((_deep: 1, _group: 0, _loop: 0, _cb: ExprTraversals.Traversal)); Info.InitFunc (ClassFuncs[j]); ClassFuncs[j].BodyCodes.TraversalWraps ((_deep: 1, _group: 0, _loop: 1, _cb: ExprTraversals.Traversal)); + ClassFuncs[j].BodyCodes.TraversalCalcType (); Info.InitFunc (ClassFuncs[j]); ClassFuncs[j].BodyCodes.TraversalWraps ((_deep: 1, _group: 0, _loop: i, _cb: ExprTraversals.Traversal)); } diff --git a/fa/fac/AntlrTools/ExprTraversals.cs b/fa/fac/AntlrTools/ExprTraversals.cs index 0175802..c7c5fa3 100644 --- a/fa/fac/AntlrTools/ExprTraversals.cs +++ b/fa/fac/AntlrTools/ExprTraversals.cs @@ -164,8 +164,9 @@ private static IAstExpr Traversal1 (IAstExpr _expr) { // 鍙傛暟1涓虹被鍚 Func _access_func2 = (_obj, _typeexpr) => { return _typeexpr switch { - AstType_Class _classexpr => _access_func (_obj, _classexpr.Class), - AstType_ArrayWrap _arrexpr when _access_name == "Length" => AstExpr_AccessBuildIn.Array_Length (_obj), + AstType_Class _classexpr => _access_func (_obj, _classexpr.Class), + AstType_ArrayWrap when _access_name == "Length" => AstExpr_AccessBuildIn.Array_Length (_obj), + AstType_String when _access_name == "Length" => AstExpr_AccessBuildIn.Array_Length (_obj), _ => throw new UnimplException (_typeexpr.Token), }; }; diff --git a/fa/fac/Info.cs b/fa/fac/Info.cs index 22b07ad..3d28554 100644 --- a/fa/fac/Info.cs +++ b/fa/fac/Info.cs @@ -108,8 +108,12 @@ public static List GetClassFromName (string _name, List _te /// public static string CurrentRelativeFile { get { - string _s = CurrentFile.Substring (SrcPath.Length); - return (_s[0] == '/' || _s[0] == '\\') ? _s.Substring(1) : _s; + if (CurrentFile.StartsWith ("res://")) { + return CurrentFile[6..]; + } else { + string _s = CurrentFile.Substring (SrcPath.Length); + return (_s[0] == '/' || _s[0] == '\\') ? _s.Substring (1) : _s; + } } } diff --git a/fa/fac/Program.cs b/fa/fac/Program.cs index 4fa7d11..f98f878 100644 --- a/fa/fac/Program.cs +++ b/fa/fac/Program.cs @@ -131,7 +131,18 @@ static void Main (string[] args) { _src_files = (from p in _src_files where p[^3..].ToLower () == ".fa" select p).ToList (); } - // TODO: 璇诲彇缂栬瘧鍣ㄨ嚜甯︽爣鍑嗗簱锛屾瘮濡侲rror绛夛紝鐢ㄤ簬鍚庣画part鎷兼帴锛屼互鍙婃浛鎹㈡帀buildin瀹炵幇 + //// TODO: 璇诲彇缂栬瘧鍣ㄨ嚜甯︽爣鍑嗗簱锛屾瘮濡侲rror绛夛紝鐢ㄤ簬鍚庣画part鎷兼帴锛屼互鍙婃浛鎹㈡帀buildin瀹炵幇 + //var _assembly = Assembly.GetExecutingAssembly (); + //var _fa_files = _assembly.GetManifestResourceNames (); + //_fa_files = (from p in _fa_files where p[..7] == "fac.fa." select p).ToArray (); + //foreach (var _fa_file in _fa_files) { + // Info.CurrentFile = $"res://fa/{_fa_file[7..]}"; + // using var _stream = _assembly.GetManifestResourceStream (_fa_file); + // using var _reader = new StreamReader (_stream, Encoding.UTF8); + // Info.CurrentSourceCode = _reader.ReadToEnd (); + // Log.Mark (LogMark.Parse); + // Info.Programs.Add (Common.ParseCode (Info.CurrentSourceCode)); + //} // 璇诲彇婧愮爜 foreach (var _src_file in _src_files) { @@ -141,42 +152,39 @@ static void Main (string[] args) { Info.Programs.Add (Common.ParseCode (Info.CurrentSourceCode)); } - //try { - // 缂栬瘧 + // 缂栬瘧 + if (Debugger.IsAttached) { foreach (var _program in Info.Programs) _program.Compile (); - //} catch (CodeException _ce) { - // if (_ce.Token != null) { - // Console.WriteLine ($"浣嶄簬 {Info.CurrentRelativeFile} 鏂囦欢绗 {_ce.Token.Line} 琛岀殑閿欒锛歿_ce.Message}"); - // int _start = Info.CurrentSourceCode.LastIndexOfAny (new char[] { '\r', '\n' }, _ce.Token.StartIndex) + 1; - // string _code = Info.CurrentSourceCode[_start..]; - // int _p = _code.IndexOfAny (new char [] { '\r', '\n' }); - // _code = _code[.._p]; - // Console.WriteLine (_code); - // var _sb = new StringBuilder (); - // for (int i = 0; i < _ce.Token.Column; ++i) { - // if (_code[i] == '\t') { - // _sb.Append ('\t'); - // } else if (((short) _code[i]) < 128) { - // _sb.Append (' '); - // } else { - // _sb.Append ('銆'); - // } - // } - // Console.WriteLine ($"{_sb}^"); - // } else { - // Console.WriteLine ($"浣嶄簬 {Info.CurrentRelativeFile} 鏂囦欢鐨勯敊璇細{_ce.Message}"); - // } - // if (Debugger.IsAttached) { - // Console.WriteLine (); - // // 閲嶅啓涓閬嶏紝姝ゅ鎶涘紓甯 - // foreach (var _program in Info.Programs) - // _program.Compile (); - // Console.WriteLine ($"鎸変换鎰忛敭閫鍑恒傘傘"); - // Console.ReadKey (); - // } - // return; - //} + } else { + try { + foreach (var _program in Info.Programs) + _program.Compile (); + } catch (CodeException _ce) { + if (_ce.Token != null) { + Console.WriteLine ($"浣嶄簬 {Info.CurrentRelativeFile} 鏂囦欢绗 {_ce.Token.Line} 琛岀殑閿欒锛歿_ce.Message}"); + int _start = Info.CurrentSourceCode.LastIndexOfAny (new char[] { '\r', '\n' }, _ce.Token.StartIndex) + 1; + string _code = Info.CurrentSourceCode[_start..]; + int _p = _code.IndexOfAny (new char [] { '\r', '\n' }); + _code = _code[.._p]; + Console.WriteLine (_code); + var _sb = new StringBuilder (); + for (int i = 0; i < _ce.Token.Column; ++i) { + if (_code[i] == '\t') { + _sb.Append ('\t'); + } else if (((short) _code[i]) < 128) { + _sb.Append (' '); + } else { + _sb.Append ('銆'); + } + } + Console.WriteLine ($"{_sb}^"); + } else { + Console.WriteLine ($"浣嶄簬 {Info.CurrentRelativeFile} 鏂囦欢鐨勯敊璇細{_ce.Message}"); + } + return; + } + } // 杈撳嚭 Directory.SetCurrentDirectory (Info.DestPath); diff --git a/fa/fac/fa/Error.fa b/fa/fac/fa/Error.fa new file mode 100644 index 0000000..debe650 --- /dev/null +++ b/fa/fac/fa/Error.fa @@ -0,0 +1,6 @@ +锘縩amespace fa; + +public enum Error { + DivideZero, + IndexOutOfBounds, +} diff --git a/fa/fac/fa/Optional.fa b/fa/fac/fa/Optional.fa new file mode 100644 index 0000000..7d300f1 --- /dev/null +++ b/fa/fac/fa/Optional.fa @@ -0,0 +1,6 @@ +锘縩amespace fa; + +public enum Optional { + Value (T1), + Error (Error), +} diff --git a/fa/fac/fac.csproj b/fa/fac/fac.csproj index 5a2860d..42bee24 100644 --- a/fa/fac/fac.csproj +++ b/fa/fac/fac.csproj @@ -3,9 +3,9 @@ Exe net5.0 - 0.0.4.0 - 0.0.4.0 - 0.0.4 + 0.0.5.0 + 0.0.5.0 + 0.0.5 Copyright 漏 2021 fawdlstty fa-org @@ -23,6 +23,20 @@ 1701;1702;3021 + + + + + + + + Never + + + Never + + + diff --git a/test/App.fa b/test/App.fa index 34c76d5..5e36471 100644 --- a/test/App.fa +++ b/test/App.fa @@ -1,18 +1,8 @@ use fa; -class Dic1 { - public T1 s; - public T1 test (T1 t) { - T1 a = "{0}{1}".Format (s, t); - return a; - } -} - class Program { public static void Main () { - Dic1 d = new { s = "Test" }; - string _s = d.test ("Object3"); - Console.Write (_s); + Console.Write ("hello"); } }