Skip to content

Commit

Permalink
minor optimizations, ie moved dfuncs and ifuncs to dictionaries than …
Browse files Browse the repository at this point in the history
…lists
  • Loading branch information
Matto58 committed May 10, 2024
1 parent abfbab7 commit 6e894c5
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 97 deletions.
164 changes: 81 additions & 83 deletions liblifetime/LTDefaultContainer.cs
Original file line number Diff line number Diff line change
@@ -1,93 +1,91 @@
namespace Mattodev.Lifetime;
public partial class LTInterpreter {
public static readonly LTRuntimeContainer DefaultContainer = new() {
IFuncs = [
// class: !sys->io
new("print", "sys", "io", "obj", LTVarAccess.Public, [], true, (c, a) => {
a.ToList().ForEach(a => LogMsg(a.Value, ref c));
return (null, null, c);
}),
new("print_line", "sys", "io", "obj", LTVarAccess.Public, [], true, (c, a) => {
a.ToList().ForEach(a => LogMsg(a.Value, ref c, true));
return (null, null, c);
}),
new("read_line", "sys", "io", "str", LTVarAccess.Public, [("str", "question")], false, (c, a) =>
(LTVar.SimpleMut("str", "_answer", c.InputHandler(a[0].Value), "sys", "io"), null, c)),
// class: !sys->tools
new("is_null", "sys", "tools", "bool", LTVarAccess.Public, [("obj", "object")], false, (c, a) => {
return (LTVar.SimpleConst("bool", "_ret", a[0].IsNull ? "true" : "false", "sys", "tools"), null, c);
}),
new("split_str", "sys", "tools", "str_array", LTVarAccess.Public, [("str", "string"), ("str", "separator")], false, (c, a) => {
return (LTVar.SimpleMut("str_array", "_arr", "", "sys", "tools"), null, c);
}),
new("create_array", "sys", "tools", "str_array", LTVarAccess.Public, [], true, (c, a) => {
return (LTVar.SimpleMut("str_array", "_arr", string.Join('\x1', a.Select(a => a.Value)), "sys", "tools"), null, c);
}),
// class: !sys->dev
new("bindns", "sys", "dev", "obj", LTVarAccess.Public, [("str", "namespace")], false, (c, a) => {
c.bindedNamespaces.Add(a[0].Value);
return (null, null, c);
}),
new("unbindns", "sys", "dev", "obj", LTVarAccess.Public, [("str", "namespace")], false, (c, a) => {
if (c.bindedNamespaces.Contains(a[0].Value))
c.bindedNamespaces.Remove(a[0].Value);
return (null, null, c);
}),
// class: !sys->fl
// todo: avoid copypaste of open_r, open_w and open_rw
new("open_r", "sys", "fl", "int32", LTVarAccess.Public, [("str", "filename")], false, (c, a) => {
if (!File.Exists(a[0].Value))
return (null, "File not found: " + a[0].Value, c);
public static readonly LTRuntimeContainer DefaultContainer = LTRuntimeContainer.Create([
// class: !sys->io
new("print", "sys", "io", "obj", LTVarAccess.Public, [], true, (c, a) => {
a.ToList().ForEach(a => LogMsg(a.Value, ref c));
return (null, null, c);
}),
new("print_line", "sys", "io", "obj", LTVarAccess.Public, [], true, (c, a) => {
a.ToList().ForEach(a => LogMsg(a.Value, ref c, true));
return (null, null, c);
}),
new("read_line", "sys", "io", "str", LTVarAccess.Public, [("str", "question")], false, (c, a) =>
(LTVar.SimpleMut("str", "_answer", c.InputHandler(a[0].Value), "sys", "io"), null, c)),
// class: !sys->tools
new("is_null", "sys", "tools", "bool", LTVarAccess.Public, [("obj", "object")], false, (c, a) => {
return (LTVar.SimpleConst("bool", "_ret", a[0].IsNull ? "true" : "false", "sys", "tools"), null, c);
}),
new("split_str", "sys", "tools", "str_array", LTVarAccess.Public, [("str", "string"), ("str", "separator")], false, (c, a) => {
return (LTVar.SimpleMut("str_array", "_arr", "", "sys", "tools"), null, c);
}),
new("create_array", "sys", "tools", "str_array", LTVarAccess.Public, [], true, (c, a) => {
return (LTVar.SimpleMut("str_array", "_arr", string.Join('\x1', a.Select(a => a.Value)), "sys", "tools"), null, c);
}),
// class: !sys->dev
new("bindns", "sys", "dev", "obj", LTVarAccess.Public, [("str", "namespace")], false, (c, a) => {
c.bindedNamespaces.Add(a[0].Value);
return (null, null, c);
}),
new("unbindns", "sys", "dev", "obj", LTVarAccess.Public, [("str", "namespace")], false, (c, a) => {
if (c.bindedNamespaces.Contains(a[0].Value))
c.bindedNamespaces.Remove(a[0].Value);
return (null, null, c);
}),
// class: !sys->fl
// todo: avoid copypaste of open_r, open_w and open_rw
new("open_r", "sys", "fl", "int32", LTVarAccess.Public, [("str", "filename")], false, (c, a) => {
if (!File.Exists(a[0].Value))
return (null, "File not found: " + a[0].Value, c);

c.Handles.Add(File.Open(a[0].Value, FileMode.Open, FileAccess.Read));
return (LTVar.SimpleConst("int32", "_handleinx", (c.Handles.Count-1).ToString(), "sys", "fl"), null, c);
}),
new("open_w", "sys", "fl", "int32", LTVarAccess.Public, [("str", "filename")], false, (c, a) => {
if (!File.Exists(a[0].Value))
return (null, "File not found: " + a[0].Value, c);
c.Handles.Add(File.Open(a[0].Value, FileMode.Open, FileAccess.Read));
return (LTVar.SimpleConst("int32", "_handleinx", (c.Handles.Count-1).ToString(), "sys", "fl"), null, c);
}),
new("open_w", "sys", "fl", "int32", LTVarAccess.Public, [("str", "filename")], false, (c, a) => {
if (!File.Exists(a[0].Value))
return (null, "File not found: " + a[0].Value, c);

c.Handles.Add(File.Open(a[0].Value, FileMode.Open, FileAccess.Write));
return (LTVar.SimpleConst("int32", "_handleinx", (c.Handles.Count-1).ToString(), "sys", "fl"), null, c);
}),
new("open_rw", "sys", "fl", "int32", LTVarAccess.Public, [("str", "filename")], false, (c, a) => {
if (!File.Exists(a[0].Value))
return (null, "File not found: " + a[0].Value, c);
c.Handles.Add(File.Open(a[0].Value, FileMode.Open, FileAccess.Write));
return (LTVar.SimpleConst("int32", "_handleinx", (c.Handles.Count-1).ToString(), "sys", "fl"), null, c);
}),
new("open_rw", "sys", "fl", "int32", LTVarAccess.Public, [("str", "filename")], false, (c, a) => {
if (!File.Exists(a[0].Value))
return (null, "File not found: " + a[0].Value, c);

c.Handles.Add(File.Open(a[0].Value, FileMode.Open, FileAccess.ReadWrite));
return (LTVar.SimpleConst("int32", "_handleinx", (c.Handles.Count-1).ToString(), "sys", "fl"), null, c);
}),
new("close", "sys", "fl", "obj", LTVarAccess.Public, [("int32", "handle")], false, (c, a) => {
int handleInx = int.Parse(a[0].Value); // ooo scary!!
if (handleInx >= c.Handles.Count)
return (null, $"Invalid handle index: {a[0].Value} (>= {c.Handles.Count} handles in container)", c);
if (c.Handles[handleInx] == null)
return (null, "Handle is closed already", c);
c.Handles.Add(File.Open(a[0].Value, FileMode.Open, FileAccess.ReadWrite));
return (LTVar.SimpleConst("int32", "_handleinx", (c.Handles.Count-1).ToString(), "sys", "fl"), null, c);
}),
new("close", "sys", "fl", "obj", LTVarAccess.Public, [("int32", "handle")], false, (c, a) => {
int handleInx = int.Parse(a[0].Value); // ooo scary!!
if (handleInx >= c.Handles.Count)
return (null, $"Invalid handle index: {a[0].Value} (>= {c.Handles.Count} handles in container)", c);
if (c.Handles[handleInx] == null)
return (null, "Handle is closed already", c);

c.Handles[handleInx]!.Close();
c.Handles[handleInx] = null;
return (null, null, c);
}),
new("read_as_str", "sys", "fl", "str", LTVarAccess.Public, [("int32", "handle")], false, (c, a) => {
int handleInx = int.Parse(a[0].Value);
if (handleInx >= c.Handles.Count)
return (null, $"Invalid handle index: {a[0].Value} (>= {c.Handles.Count} handles in container)", c);
c.Handles[handleInx]!.Close();
c.Handles[handleInx] = null;
return (null, null, c);
}),
new("read_as_str", "sys", "fl", "str", LTVarAccess.Public, [("int32", "handle")], false, (c, a) => {
int handleInx = int.Parse(a[0].Value);
if (handleInx >= c.Handles.Count)
return (null, $"Invalid handle index: {a[0].Value} (>= {c.Handles.Count} handles in container)", c);

// misnomer to call a FileStream a handle but imo it kinda makes sense
FileStream? handle = c.Handles[handleInx];
if (handle == null)
return (null, "Handle is closed", c);
if (!handle.CanRead)
return (null, "Can't read from nonreadable handle", c);
// misnomer to call a FileStream a handle but imo it kinda makes sense
FileStream? handle = c.Handles[handleInx];
if (handle == null)
return (null, "Handle is closed", c);
if (!handle.CanRead)
return (null, "Can't read from nonreadable handle", c);

string content;
long currentPos = handle.Position;
handle.Position = 0;
using (StreamReader s = new(handle, leaveOpen: true))
content = s.ReadToEnd();
handle.Position = currentPos;
string content;
long currentPos = handle.Position;
handle.Position = 0;
using (StreamReader s = new(handle, leaveOpen: true))
content = s.ReadToEnd();
handle.Position = currentPos;

return (LTVar.SimpleConst("str", "_filecontent", content, "sys", "fl"), null, c);
}),
]
};
return (LTVar.SimpleConst("str", "_filecontent", content, "sys", "fl"), null, c);
})
], []);
}
28 changes: 19 additions & 9 deletions liblifetime/LTInterpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static bool Exec(string[] source, string fileName, ref LTRuntimeContainer
container.tempValuesForInterpreter["fn_src"].Split('\x1'),
fileName
);
container.DFuncs.Add(f);
container.AppendDFunc(f);
if (DebugMode)
Console.WriteLine($"Exec: defined function {f.Name} ({f.SourceCode.Length-1} lines, {f.AcceptsArgs} args)");

Expand Down Expand Up @@ -210,16 +210,14 @@ public static void LogMsg(string msg, ref LTRuntimeContainer container, bool new
}

public static LTError? FindAndExecFunc(string id, string[] args, string file, string line, int lineNum, ref LTRuntimeContainer container) {
var indexedDFuncs = indexDFuncs(container);
var indexedIFuncs = indexIFuncs(container);
string[] s1 = id.Split("::");
if (s1.Length != 2) {
if (string.IsNullOrEmpty(s1[0]))
return new("Missing function identifier", file, line, lineNum);
if (DebugMode)
Console.WriteLine($"FindAndExecFunc: looking for !{s1[0]} in namespace '{container.Namespace}', class '{container.Class}'...");

ILifetimeFunc? f = GetFunc(container.Namespace, container.Class, s1[0], indexedDFuncs, indexedIFuncs);
ILifetimeFunc? f = GetFunc(container.Namespace, container.Class, s1[0], container.DFuncs, container.IFuncs);
if (f == null) return new($"Invalid function identifier: {id}", file, line, lineNum);

var e = ExecFunc(f, args, file, line, lineNum, ref container);
Expand All @@ -236,7 +234,7 @@ public static void LogMsg(string msg, ref LTRuntimeContainer container, bool new
funcName = s1[1];
foreach (string ns in container.bindedNamespaces) {
if (DebugMode) Console.WriteLine($"FindAndExecFunc: looking for !{funcClass}::{funcName} in binded namespace {ns}...");
func = GetFunc(ns, funcClass, funcName, indexedDFuncs, indexedIFuncs);
func = GetFunc(ns, funcClass, funcName, container.DFuncs, container.IFuncs);
if (func != null) {
var e = ExecFunc(func, args, file, line, lineNum, ref container);
container.nestedFuncExitedFine = e == null;
Expand All @@ -251,7 +249,7 @@ public static void LogMsg(string msg, ref LTRuntimeContainer container, bool new
funcClass = s2[1];
funcName = s1[1];
if (DebugMode) Console.WriteLine($"FindAndExecFunc: looking for !{funcNamespace}->{funcClass}::{funcName}...");
func = GetFunc(funcNamespace, funcClass, funcName, indexedDFuncs, indexedIFuncs);
func = GetFunc(funcNamespace, funcClass, funcName, container.DFuncs, container.IFuncs);
if (func != null) {
var e = ExecFunc(func, args, file, line, lineNum, ref container);
container.nestedFuncExitedFine = e == null;
Expand Down Expand Up @@ -361,6 +359,7 @@ public static ((string Type, string Name)[] Args, LTError? Error) ParseFuncDefAr

return null;
}
/*
internal static Dictionary<string, LTDefinedFunc> indexDFuncs(LTRuntimeContainer container) {
Dictionary<string, LTDefinedFunc> d = [];
foreach (LTDefinedFunc func in container.DFuncs)
Expand All @@ -374,17 +373,28 @@ internal static Dictionary<string, LTInternalFunc> indexIFuncs(LTRuntimeContaine
}
return d;
}
*/

internal static bool swStop(ref Stopwatch? s, string f, ref LTRuntimeContainer c, bool v = false) {
s?.Stop();
c.Handles.ForEach(h => h?.Close());
if (DebugMode) {
Console.WriteLine($"swStop: exited {f} in {s?.ElapsedMilliseconds}ms, now listing dfuncs:");
c.DFuncs.ForEach(f => Console.WriteLine($"\t{f.Type}\t!{f.Namespace}->{f.Class}::{f.Name} ({f.SourceCode.Length-1} lines)"));
c.DFuncs
.Select(a => a.Value)
.ToList()
.ForEach(f => Console.WriteLine($"\t{f.Type}\t!{f.Namespace}->{f.Class}::{f.Name} ({f.SourceCode.Length-1} lines)"));

Console.WriteLine("swStop: now ifuncs:");
c.IFuncs.ForEach(f => Console.WriteLine($"\t{f.Type}\t!{f.Namespace}->{f.Class}::{f.Name}"));
c.IFuncs
.Select(a => a.Value)
.ToList()
.ForEach(f => Console.WriteLine($"\t{f.Type}\t!{f.Namespace}->{f.Class}::{f.Name}"));

Console.WriteLine("swStop: now vars:");
c.Vars.ForEach(f => Console.WriteLine($"\t{f.Type}\t${f.Namespace}->{f.Class}::{f.Name}\t= {f.Value}"));
c.Vars
.ForEach(f => Console.WriteLine($"\t{f.Type}\t${f.Namespace}->{f.Class}::{f.Name}\t= {f.Value}"));

Console.WriteLine("swStop: binded namespaces: " + string.Join(", ", c.bindedNamespaces));
}
return v;
Expand Down
17 changes: 13 additions & 4 deletions liblifetime/LTRuntimeContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ public class LTRuntimeContainer : ICloneable {
public Func<string, string> InputHandler;
public Action<string> OutputHandler, ErrOutputHandler;
public List<LTVar> Vars;
public List<LTDefinedFunc> DFuncs;
public List<LTInternalFunc> IFuncs;
public Dictionary<string, LTDefinedFunc> DFuncs;
public Dictionary<string, LTInternalFunc> IFuncs;
public List<FileStream?> Handles;
public LTVar? LastReturnedValue;
internal List<string> bindedNamespaces = [];
Expand All @@ -26,13 +26,22 @@ public LTRuntimeContainer() {
ErrOutputHandler = _ => {};
}

public static LTRuntimeContainer Create(List<LTInternalFunc> iFuncs, List<LTDefinedFunc> dFuncs) {
LTRuntimeContainer c = new();
iFuncs.ForEach(c.AppendIFunc);
dFuncs.ForEach(c.AppendDFunc);
return c;
}
public void AppendDFunc(LTDefinedFunc f) => DFuncs.Add($"{f.Namespace}/{f.Class}/{f.Name}", f);
public void AppendIFunc(LTInternalFunc f) => IFuncs.Add($"{f.Namespace}/{f.Class}/{f.Name}", f);

public object Clone() {
LTRuntimeContainer clone = (LTRuntimeContainer)MemberwiseClone();
clone.Vars = [..Vars];
clone.DFuncs = [];
DFuncs.ForEach(f => clone.DFuncs.Add((LTDefinedFunc)f.Clone()));
DFuncs.ToList().ForEach(f => clone.AppendDFunc((LTDefinedFunc)f.Value.Clone()));
clone.IFuncs = [];
IFuncs.ForEach(f => clone.IFuncs.Add((LTInternalFunc)f.Clone()));
IFuncs.ToList().ForEach(f => clone.AppendIFunc((LTInternalFunc)f.Value.Clone()));
clone.tempValuesForInterpreter = tempValuesForInterpreter.ToDictionary(a => a.Key, a => a.Value);
return clone;
}
Expand Down
2 changes: 1 addition & 1 deletion liblifetime/liblifetime.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyVersion>0.4.1</AssemblyVersion>
<AssemblyVersion>0.4.2</AssemblyVersion>
</PropertyGroup>

</Project>

0 comments on commit 6e894c5

Please # to comment.