Skip to content

Commit ce6f54a

Browse files
committed
v1.0
0 parents  commit ce6f54a

File tree

260 files changed

+421749
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

260 files changed

+421749
-0
lines changed

.gitignore

+401
Large diffs are not rendered by default.

AAPCpp2Cli/AAPCpp2Cli.csproj

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
</Project>

AAPCpp2Cli/Program.cs

+339
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
using System;
2+
using System.Text;
3+
using System.Text.RegularExpressions;
4+
5+
class Program
6+
{
7+
private static Regex reCls = new(@"^ *(class|struct) ([A-z_0-9 ]+)\W*(\{(?:[^{}]|(?<open>\{)|(?<-open>\}))+(?(open)(?!))\})", RegexOptions.Multiline);
8+
private static Regex reCom = new(@"/\*\w+\*/");
9+
private static Regex reDeclDef = new(@"^([A-z_0-9 :<,>]+)\(([A-z_0-9\- ,=:<>&*/.\r\n]*)\)\s*((\{(?:[^{}]|(?<open>\{)|(?<-open>\}))+(?(open)(?!))\})|;)", RegexOptions.Multiline);
10+
private static Regex reImpl = new(@"^([A-z_0-9 :<,>]+)\(([A-z_0-9 ,=:<>&*/.\r\n]*)\)[\sa-z]*((:([\s ]*[A-z_0-9]+\{[A-z0-9.]+\},)+[\s ]*[A-z_0-9]+\{[A-z0-9.]+\})?\s*(\{(?:[^{}]|(?<open>\{)|(?<-open>\}))+(?(open)(?!))\}))", RegexOptions.Multiline);
11+
private static Regex reMemb = new(@"^([A-z_0-9 :<,>]+)(\{[A-z0-9.:]+\})?;", RegexOptions.Multiline);
12+
private static Regex reVector = new(@"std::vector<([^,<>]*)>");
13+
private static Regex reListInit = new(@"(System::Collections::Generic::List<[A-z0-9_]+>)\^\s*(\w+);");
14+
private static Regex reLambda = new(@"\[\]\((.*)\)\s*->\s*([A-z]+)\s*(\{(?:[^{}]|(?<open>\{)|(?<-open>\}))+(?(open)(?!))\})");
15+
private static Regex reInclude = new(@"^#include .*$", RegexOptions.Multiline);
16+
private static Regex reEndif = new(@"^#endif .*$", RegexOptions.Multiline);
17+
18+
private static string Namespace = "AAPlusSharp";
19+
20+
public static int Main(string[] args)
21+
{
22+
if (args.Length != 2)
23+
return 1;
24+
25+
Console.WriteLine("currently no AAVSOP2013");
26+
27+
var input = args[0];
28+
var output = args[1];
29+
30+
Directory.CreateDirectory(output);
31+
var exclusion = new string[] { "AA+.h", "stdafx.h", "stdafx.cpp" };
32+
33+
foreach (var p in Directory.EnumerateFiles(input, "*.h"))
34+
{
35+
using var sr = new StreamReader(p);
36+
using var sw = new StreamWriter(Path.Combine(output, Path.GetFileName(p)));
37+
if (exclusion.Any(e => p.EndsWith(e)))
38+
sw.Write(sr.ReadToEnd());
39+
else
40+
sw.Write(ProcessHeader(sr.ReadToEnd()));
41+
}
42+
43+
foreach (var p in Directory.EnumerateFiles(input, "*.cpp"))
44+
{
45+
using var sr = new StreamReader(p);
46+
using var sw = new StreamWriter(Path.Combine(output, Path.GetFileName(p)));
47+
if (exclusion.Any(e => p.EndsWith(e)))
48+
sw.Write(sr.ReadToEnd());
49+
else
50+
sw.Write(ProcessImpl(sr.ReadToEnd()));
51+
}
52+
53+
return 0;
54+
}
55+
56+
private static string RemoveQualifiers(string cpp)
57+
{
58+
var cli = new StringBuilder(cpp);
59+
cli.Replace(") noexcept", ")");
60+
cli.Replace(") const noexcept", ")");
61+
cli.Replace("constexpr ", "");
62+
cli.Replace("const ", ""); // !!!
63+
cli.Replace(" const", ""); // !!!
64+
return cli.ToString();
65+
}
66+
67+
private static string ReplaceStd(string cpp)
68+
{
69+
//var cli = new StringBuilder(cpp);
70+
//cli.Replace("#include <vector>", "#include \"AAPArray.h\"");
71+
//cli.Replace("std::vector", "AAPArray");
72+
//return cli.ToString();
73+
74+
//cpp = cpp.Replace("#include <vector>", "#include \"AAPArray.h\"");
75+
cpp = cpp.Replace("#include <vector>", "");
76+
//cpp = reVector.Replace(cpp, "AAPArray<$1>");
77+
cpp = reVector.Replace(cpp, "System::Collections::Generic::List<$1>^");
78+
cpp = cpp.Replace(".push_back", "->Add");
79+
cpp = reListInit.Replace(cpp, "$1^ $2 = gcnew $1(0);");
80+
return cpp;
81+
}
82+
83+
public static string ProcessHeader(string cpp)
84+
{
85+
cpp = RemoveQualifiers(cpp);
86+
cpp = ReplaceStd(cpp);
87+
88+
var cli = new StringBuilder(cpp);
89+
var matches = reCls.Matches(cpp);
90+
foreach (Match m in matches.Reverse<Match>())
91+
{
92+
var name = m.Groups[2].Value;
93+
if (name.Contains("Coefficient"))
94+
{
95+
// native type, do nothing
96+
}
97+
else
98+
{
99+
var type = m.Groups[1].Value;
100+
//var isRef = type == "class";
101+
//var isRef = !name.Contains("Details2");
102+
var body = ProcessHeaderClassBody(out var isRef, name, m.Groups[3].Value);
103+
var rv = isRef ? "ref" : "value";
104+
var cls = $"public {rv} {type} {name}\r\n{body}";
105+
cli.Remove(m.Index, m.Length);
106+
cli.Insert(m.Index, cls);
107+
}
108+
}
109+
cpp = cli.ToString();
110+
111+
cpp = EdgeCases(cpp);
112+
if (matches.Count > 0)
113+
cpp = AddNamespace(cpp, matches[0].Index, reEndif.Matches(cpp).Last().Index);
114+
115+
return cpp;
116+
}
117+
118+
public static string ProcessHeaderClassBody(out bool isRef, string name, string body)
119+
{
120+
int numMethods = reDeclDef.Matches(body).Count;
121+
body = FixHeaderOverload(body, reDeclDef.Matches(body));
122+
body = FixHeaderRefPointer(body, reDeclDef.Matches(body));
123+
124+
// pure data struct, require copy constructor and operator=
125+
//if (isRef && numMethods == 0)
126+
//{
127+
// var co = GenConstructorAndOperator(name, body);
128+
// var bd = new StringBuilder(body);
129+
// bd.Insert(body.Length - 1, co);
130+
// body = bd.ToString();
131+
//}
132+
isRef = numMethods > 0;
133+
if (!isRef)
134+
{
135+
body = reMemb.Replace(body, "$1;");
136+
}
137+
138+
return body;
139+
}
140+
141+
private static string FixHeaderRefPointer(string body, MatchCollection matches)
142+
{
143+
var bd = new StringBuilder(body);
144+
foreach (var m in matches.Reverse())
145+
{
146+
var param = m.Groups[2].Value;
147+
param = reCom.Replace(param, string.Empty);
148+
param = param.Replace('&', '%');
149+
//param = param.Replace('*', '^');
150+
bd.Remove(m.Groups[2].Index, m.Groups[2].Length);
151+
bd.Insert(m.Groups[2].Index, param);
152+
}
153+
body = bd.ToString();
154+
return body;
155+
}
156+
157+
private static string FixHeaderOverload(string body, MatchCollection matches)
158+
{
159+
var bd = new StringBuilder(body);
160+
foreach (var m in matches.Reverse())
161+
{
162+
var param = m.Groups[2].Value;
163+
if (param.Contains('='))
164+
{
165+
var ol = GenOverloads(m);
166+
bd.Remove(m.Index, m.Length);
167+
bd.Insert(m.Index, ol);
168+
}
169+
}
170+
body = bd.ToString();
171+
return body;
172+
}
173+
174+
public static string GenOverloads(Match m)
175+
{
176+
var ol = new StringBuilder();
177+
var qualName = m.Groups[1].Value;
178+
var sptOpt = StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries;
179+
var name = qualName.Split(' ', sptOpt).Last();
180+
var paramList = m.Groups[2].Value.Split(',', sptOpt);
181+
var normParams = paramList.TakeWhile(p => !p.Contains('=')).ToArray();
182+
var normParamNames = normParams.Select(p => p.Split(' ', sptOpt).Last());
183+
var defParams = paramList.SkipWhile(p => !p.Contains('=')).ToArray();
184+
var defParamTypeNameValues = defParams.Select(p => p.Split('=', sptOpt)).ToArray();
185+
var defParamTpyeNames = defParamTypeNameValues.Select(tnv => tnv[0]);
186+
var defParamNames = defParamTpyeNames.Select(tn => tn.Split(' ', sptOpt).Last());
187+
var defParamValues = defParamTypeNameValues.Select(tnv => tnv[1]);
188+
var body = m.Groups[3].Value;
189+
ol.Append(qualName);
190+
ol.Append('(');
191+
ol.Append(string.Join(", ", normParams.Concat(defParamTpyeNames)));
192+
ol.Append(')');
193+
ol.AppendLine(body);
194+
for (var i = 0; i < defParams.Length; i++)
195+
{
196+
ol.Append(qualName);
197+
ol.Append('(');
198+
ol.Append(string.Join(", ", normParams.Concat(defParamTpyeNames.Take(i))));
199+
ol.Append(") { return ");
200+
ol.Append(name);
201+
ol.Append('(');
202+
var actualParam = normParamNames.Concat(defParamNames.Take(i))
203+
.Concat(defParamValues.TakeLast(defParams.Length - i));
204+
ol.Append(string.Join(", ", actualParam));
205+
ol.AppendLine("); }");
206+
}
207+
return ol.ToString();
208+
}
209+
210+
public static string GenConstructorAndOperator(string name, string body)
211+
{
212+
var sptOpt = StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries;
213+
214+
var membs = reMemb.Matches(body);
215+
var membNames = membs.Select(m => m.Groups[1].Value.Split(' ', sptOpt).Last()).ToArray();
216+
var assign = string.Join("\r\n", membNames.Select(n => $" {n} = other.{n};"));
217+
218+
name = name.Split(' ', sptOpt).Last();
219+
var co = new StringBuilder();
220+
co.AppendLine("public:");
221+
co.AppendLine($" {name}() {{}}");
222+
co.AppendLine($" {name}({name}% other)\r\n {{");
223+
co.AppendLine(assign);
224+
co.AppendLine(" }");
225+
//co.AppendLine($" {name}% operator=({name} other)\r\n {{");
226+
//co.AppendLine(assign);
227+
//co.AppendLine(" return *this;");
228+
//co.AppendLine(" }");
229+
//co.AppendLine($" {name}% operator=({name}% other)\r\n {{");
230+
//co.AppendLine(assign);
231+
//co.AppendLine(" return *this;");
232+
//co.AppendLine(" }");
233+
co.AppendLine($" void operator=({name}% other)\r\n {{");
234+
co.AppendLine(assign);
235+
co.AppendLine(" }");
236+
return co.ToString();
237+
}
238+
239+
public static string ProcessImpl(string cpp)
240+
{
241+
cpp = RemoveQualifiers(cpp);
242+
cpp = ReplaceStd(cpp);
243+
244+
var cli = new StringBuilder(cpp);
245+
var lambdas = new Dictionary<string, string>();
246+
var matches = reImpl.Matches(cpp);
247+
foreach (var m in matches.Reverse())
248+
{
249+
var impl = ProcessImplBody(m.Groups[1].Value, m.Groups[2].Value, m.Groups[3].Value, ref lambdas);
250+
cli.Remove(m.Index, m.Length);
251+
cli.Insert(m.Index, impl);
252+
}
253+
if (lambdas.Count > 0)
254+
{
255+
var lds = String.Join("\r\n", lambdas.Values);
256+
cli.Insert(matches[0].Index, lds);
257+
}
258+
cpp = cli.ToString();
259+
260+
cpp = EdgeCases(cpp);
261+
262+
cli = new StringBuilder(cpp);
263+
var lastInclude = reInclude.Matches(cpp).Last();
264+
cli.Insert(lastInclude.Index + lastInclude.Length + 1, $"using namespace {Namespace};");
265+
cpp = cli.ToString();
266+
return cpp;
267+
}
268+
269+
public static string ProcessImplBody(string qualName, string paramList, string initBody, ref Dictionary<string, string> lambdas)
270+
{
271+
paramList = reCom.Replace(paramList, string.Empty);
272+
paramList = paramList.Replace('&', '%');
273+
//paramList = paramList.Replace('*', '^');
274+
275+
foreach (var m in reLambda.Matches(initBody).Reverse())
276+
{
277+
var li = lambdas.Count;
278+
var name = $"_CliGenLambda{li}";
279+
var pl = m.Groups[1].Value;
280+
pl = $"const {pl.Replace(",", ", const ")}"; // A temp fix
281+
lambdas[name] = $"{m.Groups[2].Value} {name}({pl}){m.Groups[3].Value}\r\n";
282+
var ib = new StringBuilder(initBody);
283+
ib.Remove(m.Index, m.Length);
284+
ib.Insert(m.Index, name);
285+
initBody = ib.ToString();
286+
}
287+
288+
var impl = new StringBuilder();
289+
impl.Append(qualName);
290+
impl.Append('(');
291+
impl.Append(paramList);
292+
impl.Append(")");
293+
if (initBody[0] == ':')
294+
impl.Append(' ');
295+
else
296+
impl.AppendLine();
297+
impl.Append(initBody);
298+
return impl.ToString();
299+
}
300+
301+
private static string AddNamespace(string cpp, int beg, int end)
302+
{
303+
var cli = new StringBuilder(cpp);
304+
cli.Insert(end, "}\r\n");
305+
cli.Insert(beg, $"namespace {Namespace}\r\n{{\r\n");
306+
return cli.ToString();
307+
}
308+
309+
private static string EdgeCases(string cpp)
310+
{
311+
// AAJewishCalendar.cpp L80,83
312+
//cpp = cpp.Replace("const CAADate CurrentYear{CivilYear, CurrentPesach.Month, static_cast<double>(CurrentPesach.Day), bGregorian};",
313+
// "CAADate CurrentYear{CivilYear, CurrentPesach.Month, static_cast<double>(CurrentPesach.Day), bGregorian};");
314+
//cpp = cpp.Replace("const CAADate NextYear{CivilYear+1, NextPesach.Month, static_cast<double>(NextPesach.Day), bGregorian};",
315+
// "CAADate NextYear{CivilYear+1, NextPesach.Month, static_cast<double>(NextPesach.Day), bGregorian};");
316+
317+
// AADynamicalTime.h, L67
318+
cpp = cpp.Replace("static DELTAT_PROC sm_pDeltaTProc;",
319+
"static DELTAT_PROC sm_pDeltaTProc{ nullptr };");
320+
// AADynamicalTime.cpp, L19771
321+
cpp = cpp.Replace("CAADynamicalTime::DELTAT_PROC CAADynamicalTime::sm_pDeltaTProc{nullptr};",
322+
"//CAADynamicalTime::DELTAT_PROC CAADynamicalTime::sm_pDeltaTProc{nullptr};");
323+
324+
// AADynamicalTime.cpp, L19813
325+
//cpp = cpp.Replace("const CAADate date{JD, CAADate::AfterPapalReform(JD)};",
326+
// "CAADate date{JD, CAADate::AfterPapalReform(JD)};");
327+
328+
// ...
329+
cpp = cpp.Replace("CAA3DCoordinate*", "CAA3DCoordinate^");
330+
cpp = cpp.Replace("CAA3DCoordinate Ecliptic{EclipticRectangularCoordinates(pT, nTSize, correction, &EclipticDerivative)};",
331+
"CAA3DCoordinate Ecliptic{EclipticRectangularCoordinates(pT, nTSize, correction, %EclipticDerivative)};");
332+
333+
// AAELP2000.cpp, L107 && AAELPMPP02.cpp, L252
334+
cpp = cpp.Replace("std::array<std::array<double, 2>, 8> g_P",
335+
"static std::array<std::array<double, 2>, 8> g_P");
336+
337+
return cpp;
338+
}
339+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"profiles": {
3+
"AAPCpp2Cli": {
4+
"commandName": "Project",
5+
"commandLineArgs": "..\\..\\..\\..\\aaplus ..\\..\\..\\..\\AAPlusSharp"
6+
}
7+
}
8+
}

0 commit comments

Comments
 (0)