Skip to content

Commit

Permalink
MoLang fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kennyvv committed Dec 23, 2021
1 parent fc1246a commit 1e14a3a
Show file tree
Hide file tree
Showing 17 changed files with 179 additions and 260 deletions.
30 changes: 27 additions & 3 deletions src/Alex.MoLang.TestApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Json;
Expand All @@ -27,20 +28,33 @@ static void Main(string[] args)

TokenIterator tokenIterator = new TokenIterator(@"t.a = 213 + 2 / 0.5 + 5 + 2 * 3;
query.debug_output(1 + 2 * 3);
array.test.0 = 100;
array.test[1] = 200;
array.test[2] = 10.5;
query.debug_output(array.test[1]);
t.b = 3;
loop(10, {
array.test[t.b] = array.test[t.b - 1] + 2;
t.b = t.b + 1;
});
for_each(v.r, array.test, {
t.a = t.a + v.r;
query.debug_output('hello1', t.a, v.r);
});
t.b = 0;
loop(10, {
t.b = t.b + 1;
t.a = t.a + math.cos((Math.PI / 180.0f) * 270);
query.debug_output('hello', 'test', t.a, array.test[2]);
query.debug_output(array.test[t.b]);
query.debug_output('hello', 'test', t.a, array.test[2], t.b);
});
query.debug_output(query.life_time());
return t.a;");
MoLangParser parser = new MoLangParser(tokenIterator);

Expand All @@ -57,17 +71,20 @@ static void Main(string[] args)

try
{
const int runs = 100000;
const int runs = 1;///10000;
const int warmup = 5;
double totalTicks = 0;

double longest = 0;
double shortest =long.MaxValue;

IMoValue value;
for (int i = 0; i < runs; i++)
for (int i = 0; i < runs + warmup; i++)
{
sw.Restart();
value = runtime.Execute(expressions);
if (i < warmup)
continue;

var elapsed = sw.Elapsed.TotalMilliseconds;

Expand Down Expand Up @@ -118,5 +135,12 @@ public double Lifetime
return _sw.Elapsed.TotalSeconds;
}
}

[MoFunction("debug_output")]
public void DebugOutput(MoParams mo)
{
var str = string.Join(" ", mo.GetParams().Select(x => x.AsString()));
Console.WriteLine(str);
}
}
}
254 changes: 77 additions & 177 deletions src/Alex.MoLang/Parser/ExprTraverser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,216 +32,112 @@ public static IExpression FindFirst(Predicate<IExpression> predicate, params IEx
}
public class ExprTraverser
{
private bool _stopTraversal = false;

public readonly List<IExprVisitor> Visitors = new List<IExprVisitor>();

public IEnumerable<IExpression> Traverse(IEnumerable<IExpression> expressions)
private bool _stop = false;
public IExpression[] Traverse(IExpression[] expressions)
{
var enumerable = expressions as IExpression[] ?? expressions.ToArray();

foreach (IExprVisitor visitor in Visitors) {
visitor.BeforeTraverse(enumerable);
}

_stopTraversal = false;

foreach (var expression in TraverseArray(enumerable))
{
yield return expression;
}
//TraverseArray(expressions);

foreach (IExprVisitor visitor in Visitors) {
visitor.AfterTraverse(enumerable);
}
TraverseArray(expressions);

// return expressions;
return expressions.Where(x => x != null).ToArray();
}

private IEnumerable<IExpression> TraverseArray(IEnumerable<IExpression> expressions)
private void TraverseArray(IExpression[] expressions)
{
//var list = expressions.ToList();
foreach (IExprVisitor visitor in Visitors) {
visitor.BeforeTraverse(expressions);
}

//for (var i = 0; i < list.Count; i++)
//for (var index = 0; index < expressions.Length; index++)
foreach(var e in expressions)
for (var index = 0; index < expressions.Length; index++)
{
var expression = e;
// IExpression expression = expressions[index];

IExpression expression = expressions[index];

if (expression == null)
throw new MoLangRuntimeException("Expression was null", null);

var removeCurrent = false;
var traverseChildren = true;
var traverseCurrent = true;
expressions[index] = TraverseExpr(expression, null);

foreach (var visitor in Visitors)
{
var result = visitor.OnVisit(expression);

if (result is ActionType at)
{
switch (at)
{
case ActionType.RemoveCurrent:
removeCurrent = true;

break;

case ActionType.StopTraversal:
_stopTraversal = true;

break;

case ActionType.DontTraverseCurrentAndChildren:
traverseCurrent = false;
traverseChildren = false;

break;

case ActionType.DontTraverseChildren:
traverseChildren = false;

break;
}
}
else if (result is IExpression result1)
{
expression = result1;
}
}

if (!traverseCurrent)
if (_stop)
{
break;
}
}

if (traverseChildren && !removeCurrent)
{
expression = TraverseExpr(expression);
}
foreach (IExprVisitor visitor in Visitors) {
visitor.AfterTraverse(expressions);
}

foreach (IExprVisitor visitor in Visitors)
//return expressions.Where(x => x != null).ToArray();
}

private IExpression TraverseExpr(IExpression expression, IExpression parent)
{
Visit(expression);
expression.Meta.Parent = parent;
foreach (var field in GetAllProperties(expression.GetType()))
{
if (!typeof(IEnumerable<Expression>).IsAssignableFrom(field.PropertyType)
&& !typeof(IExpression).IsAssignableFrom(field.PropertyType))
{
visitor.OnLeave(expression);
continue;
}

if (removeCurrent)

//field.setAccessible(true);
var fieldValue = GetFieldValue(field, expression);
if (fieldValue == null)
continue;

if (fieldValue is IExpression original)
{
//list.Remove(expression);
// expressions[index] = null;//.Remove(expression);
fieldValue = TraverseExpr(original, expression);
}
else
else if (fieldValue is IEnumerable<IExpression> expressions)
{
// expressions[index] = expression;

yield return expression;
//expressions[i] = expression;//.set(i, expression);
var exprs = expressions.ToArray();
foreach (var ex in exprs)
{
if (ex != null)
ex.Meta.Parent = expression;
}
TraverseArray(exprs);

fieldValue = exprs;
}

SetFieldValue(field, expression, fieldValue);

if (_stopTraversal)
if (_stop)
{
break;
}
}

//return expressions.Where(x => x != null).ToArray();
OnLeave(expression);
return expression;
}

private IExpression TraverseExpr(IExpression expression)
private void Visit(IExpression expression)
{
foreach (var field in GetAllProperties(expression.GetType()))
// VisitationResult visitationResult = VisitationResult.None;
foreach (var visitor in Visitors)
{
//field.setAccessible(true);
var fieldValue = GetFieldValue(field, expression);

if (fieldValue is IExpression subExpr)
{
var removeCurrent = false;
var traverseChildren = true;
var traverseCurrent = true;

foreach (var visitor in Visitors)
{
var result = visitor.OnVisit(subExpr);

if (result is ActionType at)
{
switch (at)
{
case ActionType.RemoveCurrent:
removeCurrent = true;
break;

case ActionType.StopTraversal:
_stopTraversal = true;

break;

case ActionType.DontTraverseCurrentAndChildren:
traverseCurrent = false;
traverseChildren = false;

break;

case ActionType.DontTraverseChildren:
traverseChildren = false;

break;
}
}
else if (result is IExpression result1)
{
subExpr = result1;
}
}

if (!traverseCurrent)
{
break;
}

if (traverseChildren && !removeCurrent)
{
subExpr = TraverseExpr(subExpr);
}

foreach (var visitor in Visitors)
{
visitor.OnLeave(subExpr);
}

if (removeCurrent)
{
SetFieldValue(field, expression, null);
}
else
{
if (subExpr != fieldValue)
SetFieldValue(field, expression, subExpr);
}

if (_stopTraversal)
{
break;
}
}
else if (fieldValue != null && fieldValue.GetType().IsArray)
{
var array = (object[]) fieldValue;
//var exprs = array.Where(x => x is IExpression).Cast<IExpression>().ToArray();
visitor.OnVisit(this, expression);
}

//exprs = TraverseArray(array.Where(x => x is IExpression).Cast<IExpression>()).ToArray();
// return visitationResult;
}

SetFieldValue(
field, expression,
TraverseArray(array.Where(x => x is IExpression).Cast<IExpression>()).ToArray());
}
private void OnLeave(IExpression expression)
{
foreach (var visitor in Visitors)
{
visitor.OnLeave(expression);
}
}

return expression;
public void Stop()
{
_stop = true;
}

private static ConcurrentDictionary<Type, PropertyInfo[]> _cachedProperties =
Expand Down Expand Up @@ -284,12 +180,16 @@ private void SetFieldValue(PropertyInfo field, object obj, object value)
}
}

public enum ActionType
[Flags]
public enum VisitationResult
{
RemoveCurrent,
StopTraversal,
DontTraverseCurrentAndChildren,
DontTraverseChildren
None,

RemoveCurrent = 0x01,
StopTraversal = 0x02,
DontTraverseChildren = 0x04,
DontTraverseCurrent = 0x08,
DontTraverseCurrentAndChildren = DontTraverseCurrent | DontTraverseChildren
}
}
}
Loading

0 comments on commit 1e14a3a

Please sign in to comment.