Skip to content

Commit

Permalink
0.0.5 complete built-in methods
Browse files Browse the repository at this point in the history
  • Loading branch information
fawdlstty committed Dec 22, 2021
1 parent f3ec076 commit 3588eaa
Show file tree
Hide file tree
Showing 17 changed files with 171 additions and 80 deletions.
1 change: 1 addition & 0 deletions fa/fac.Test/BuildTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<AstProgram> (Info.CurrentSourceCode = _code));
Expand Down
47 changes: 47 additions & 0 deletions fa/fac.Test/UnitTest00_hello.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
2 changes: 1 addition & 1 deletion fa/fac/ASTs/Exprs/AstExpr_AccessBuildIn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()",
Expand Down
2 changes: 1 addition & 1 deletion fa/fac/ASTs/Exprs/AstExpr_BaseId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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}");
}
}

Expand Down
2 changes: 2 additions & 0 deletions fa/fac/ASTs/Exprs/AstExpr_OpN.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 ();
}

Expand Down
58 changes: 33 additions & 25 deletions fa/fac/ASTs/Exprs/Names/AstExprName_BuildIn.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using fac.ASTs.Types;
using fac.ASTs.Stmts;
using fac.ASTs.Types;
using fac.Exceptions;
using System;
using System.Collections.Generic;
Expand All @@ -15,17 +16,27 @@ public class AstExprName_BuildIn: IAstExprName {


private static Dictionary<string, AstExprName_BuildIn> sBuildIn = new Dictionary<string, AstExprName_BuildIn> {
["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<string, void>" },
["Console.Write"] = new AstExprName_BuildIn { Token = null, Name = "Console.Write", NameType = "Func<string, void>" },
["string.Format"] = new AstExprName_BuildIn { Token = null, Name = "string.Format", NameType = "Func<string, params any[], string>" },
["File.Exists"] = new AstExprName_BuildIn { Token = null, Name = "File.Exists", NameType = "Func<string, bool>" },
["File.ReadAllText"] = new AstExprName_BuildIn { Token = null, Name = "File.ReadAllText", NameType = "Func<string, string>" },
["File.WriteAllText"] = new AstExprName_BuildIn { Token = null, Name = "File.WriteAllText", NameType = "Func<string, string, void>" },
["File.AppendAllText"] = new AstExprName_BuildIn { Token = null, Name = "File.AppendAllText", NameType = "Func<string, string, void>" },
["@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<string, void>" },
["Console.Write"] = new AstExprName_BuildIn { Name = "Console.Write", NameType = "Func<string, void>" },
//
["string.Format"] = new AstExprName_BuildIn { Name = "string.Format", NameType = "Func<string, params any[], string>" },
//
["File.Exists"] = new AstExprName_BuildIn { Name = "File.Exists", NameType = "Func<string, bool>" },
["File.ReadAllText"] = new AstExprName_BuildIn { Name = "File.ReadAllText", NameType = "Func<string, string>" },
["File.WriteAllText"] = new AstExprName_BuildIn { Name = "File.WriteAllText", NameType = "Func<string, string, void>" },
["File.AppendAllText"] = new AstExprName_BuildIn { Name = "File.AppendAllText", NameType = "Func<string, string, void>" },
["File.Delete"] = new AstExprName_BuildIn { Name = "File.Delete", NameType = "Func<string, void>" },
//
["Directory.Exists"] = new AstExprName_BuildIn { Name = "Directory.Exists", NameType = "Func<string, bool>" },
["Directory.Create"] = new AstExprName_BuildIn { Name = "Directory.Create", NameType = "Func<string, void>" },
["Directory.Delete"] = new AstExprName_BuildIn { Name = "Directory.Delete", NameType = "Func<string, void>" },
["Directory.GetFiles"] = new AstExprName_BuildIn { Name = "Directory.GetFiles", NameType = "Func<string, string[]>" },
//
["@FILE"] = new AstExprName_BuildIn { Name = "@FILE", NameType = "string" },
["@FILEDATA"] = new AstExprName_BuildIn { Name = "@FILEDATA", NameType = "string" },
};

public static AstExprName_BuildIn FindFromName (string _name) {
Expand All @@ -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<IAstStmt>, IAstExpr) ExpandExpr ((IAstExprName _var, AstStmt_Label _pos)? _cache_err) {
// TODO 扩展写文件之类的错误判断
return (new List<IAstStmt> (), 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;
Expand Down
1 change: 1 addition & 0 deletions fa/fac/ASTs/Structs/AstClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
1 change: 1 addition & 0 deletions fa/fac/ASTs/Structs/AstEnum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
1 change: 1 addition & 0 deletions fa/fac/ASTs/Structs/AstTemplateClassInst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
1 change: 1 addition & 0 deletions fa/fac/ASTs/Structs/AstTemplateEnumInst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
5 changes: 3 additions & 2 deletions fa/fac/AntlrTools/ExprTraversals.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,9 @@ private static IAstExpr Traversal1 (IAstExpr _expr) {
// 参数1为类名
Func<IAstExpr, IAstType, IAstExpr> _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),
};
};
Expand Down
8 changes: 6 additions & 2 deletions fa/fac/Info.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,12 @@ public static List<IAstClass> GetClassFromName (string _name, List<IAstType> _te
/// </summary>
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;
}
}
}

Expand Down
78 changes: 43 additions & 35 deletions fa/fac/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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: 读取编译器自带标准库,比如Error等,用于后续part拼接,以及替换掉buildin实现
//// TODO: 读取编译器自带标准库,比如Error等,用于后续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<AstProgram> (Info.CurrentSourceCode));
//}

// 读取源码
foreach (var _src_file in _src_files) {
Expand All @@ -141,42 +152,39 @@ static void Main (string[] args) {
Info.Programs.Add (Common.ParseCode<AstProgram> (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);
Expand Down
6 changes: 6 additions & 0 deletions fa/fac/fa/Error.fa
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace fa;

public enum Error {
DivideZero,
IndexOutOfBounds,
}
6 changes: 6 additions & 0 deletions fa/fac/fa/Optional.fa
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace fa;

public enum Optional<T1> {
Value (T1),
Error (Error),
}
20 changes: 17 additions & 3 deletions fa/fac/fac.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<AssemblyVersion>0.0.4.0</AssemblyVersion>
<FileVersion>0.0.4.0</FileVersion>
<Version>0.0.4</Version>
<AssemblyVersion>0.0.5.0</AssemblyVersion>
<FileVersion>0.0.5.0</FileVersion>
<Version>0.0.5</Version>
<Copyright>Copyright © 2021</Copyright>
<Authors>fawdlstty</Authors>
<Company>fa-org</Company>
Expand All @@ -23,6 +23,20 @@
<NoWarn>1701;1702;3021</NoWarn>
</PropertyGroup>

<ItemGroup>
<None Remove="fa\Error.fa" />
<None Remove="fa\Optional.fa" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="fa\Error.fa">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="fa\Optional.fa">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Antlr4.Runtime.Standard" Version="4.9.2" />
</ItemGroup>
Expand Down
12 changes: 1 addition & 11 deletions test/App.fa
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
use fa;

class Dic1<T1> {
public T1 s;
public T1 test (T1 t) {
T1 a = "{0}{1}".Format (s, t);
return a;
}
}

class Program {
public static void Main () {
Dic1<string> d = new { s = "Test" };
string _s = d.test ("Object3");
Console.Write (_s);
Console.Write ("hello");
}
}

Expand Down

0 comments on commit 3588eaa

Please sign in to comment.