Skip to content

Commit

Permalink
Merge pull request #260 from stevehalliwell/soa
Browse files Browse the repository at this point in the history
Merge soa into main: Add desugar based SOA
  • Loading branch information
stevehalliwell committed Jun 21, 2024
2 parents 2463142 + 60dc86b commit a33b440
Show file tree
Hide file tree
Showing 17 changed files with 821 additions and 22 deletions.
8 changes: 4 additions & 4 deletions ulox-vscode/syntaxes/ulox.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
},
{
"name": "keyword.operator.binary.ulox",
"match": "\\b(update|expect)\\b"
"match": "\\b(update)\\b"
},
{
"name": "keyword.language.null.ulox",
Expand Down Expand Up @@ -89,7 +89,7 @@
}
},
{
"match": "\\b(class|enum)\\s+([A-Za-z_][A-Za-z0-9_]*)(?:\\s*(<)\\s*([A-Za-z_][A-Za-z0-9_]*))?\\b",
"match": "\\b(class|enum|soa)\\s+([A-Za-z_][A-Za-z0-9_]*)(?:\\s*(<)\\s*([A-Za-z_][A-Za-z0-9_]*))?\\b",
"captures": {
"1": {
"name": "storage.type.class.ulox"
Expand Down Expand Up @@ -119,11 +119,11 @@
},
{
"name": "keyword.contextname.ulox",
"match": "\\b(fname|cname|tcname|tsname)\\b"
"match": "\\b(fname|cname|tname|tsname)\\b"
},
{
"name": "keyword.bultin.ulox",
"match": "\\b(typeof|countof|mixin|static|build|init|var)\\b"
"match": "\\b(typeof|countof|mixin|static|build|init|var|expect)\\b"
}
]
},
Expand Down
82 changes: 82 additions & 0 deletions ulox/ulox.core.bench/ObjectVsSoa.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
namespace ULox.Core.Bench
{
public class ObjectVsSoa
{
public const string ObjectBasedScript = @"
class Foo
{
var
x = 0,
y = 0,
vx = 0,
vy = 0,
;
}
var foos = [];
fun TickAllFoos(foos, dt)
{
var count = foos.Count();
for(var i = 0; i < count; i +=1)
{
var item = foos[i];
item.x = item.x + item.vx * dt;
item.y = item.y + item.vy * dt;
}
}
for(var i = 0; i < 1000; i+=1)
{
foos.Add(Foo());
}
for(var i = 0; i < 1000; i+=1)
{
TickAllFoos(foos, 0.01);
}
";


public const string SoaBasedScript = @"
class Foo
{
var
x = 0,
y = 0,
vx = 0,
vy = 0,
;
}
soa FooSet
{
Foo
}
var foos = FooSet();
fun TickAllFoos(foos, dt)
{
var count = foos.Count();
for(var i = 0; i < count; i +=1)
{
foos.x[i] = foos.x[i] + foos.vx[i] * dt;
foos.y[i] = foos.y[i] + foos.vy[i] * dt;
}
}
for(var i = 0; i < 1000; i+=1)
{
foos.Add(Foo());
}
for(var i = 0; i < 1000; i+=1)
{
TickAllFoos(foos, 0.01);
}
";
}
}
24 changes: 19 additions & 5 deletions ulox/ulox.core.bench/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,33 @@ static void Main(string[] args)
BenchmarkRunner.Run<Program>(args: args);
}

//[Benchmark]
//public void ScriptVsNativeFunctional_UloxMethods()
//{
// var engine = Engine.CreateDefault();
// //todo need to look at the byteocode for this, see if we can speed it up
// engine.RunScript(new Script("", ScriptVsNativeFunctional.FunctionalUlox));
//}

//[Benchmark]
//public void ScriptVsNativeFunctional_NativeMethods()
//{
// var engine = Engine.CreateDefault();
// engine.RunScript(new Script("", ScriptVsNativeFunctional.FunctionalNative));
//}

[Benchmark]
public void ScriptVsNativeFunctional_UloxMethods()
public void Object_PosVelUpdate()
{
var engine = Engine.CreateDefault();
//todo need to look at the byteocode for this, see if we can speed it up
engine.RunScript(new Script("", ScriptVsNativeFunctional.FunctionalUlox));
engine.RunScript(new Script("", ObjectVsSoa.ObjectBasedScript));
}

[Benchmark]
public void ScriptVsNativeFunctional_NativeMethods()
public void Soa_PosVelUpdate()
{
var engine = Engine.CreateDefault();
engine.RunScript(new Script("", ScriptVsNativeFunctional.FunctionalNative));
engine.RunScript(new Script("", ObjectVsSoa.SoaBasedScript));
}

[Benchmark]
Expand Down
21 changes: 20 additions & 1 deletion ulox/ulox.core.tests/ClassTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,25 @@ class T
// Assert.AreEqual("this should fail to find name", testEngine.InterpreterResult);
// }

[Test]
public void StaticMethod_WhenBound_ShouldSucceed()
{
testEngine.Run(@"
class T
{
static Method()
{
retval = 7;
}
}
var ret = T.Method;
print(ret());");

Assert.AreEqual("7", testEngine.InterpreterResult);
}

[Test]
public void Prop_WhenCalledOnClass_ShouldFail()
{
Expand All @@ -1032,7 +1051,7 @@ class T
var a = T.foo;");

StringAssert.StartsWith("Undefined property 'foo', cannot bind method as it has no fromClass a", testEngine.InterpreterResult);
StringAssert.StartsWith("Undefined method 'foo', no method found on usertype'<Class T>' at", testEngine.InterpreterResult);
}

[Test]
Expand Down
32 changes: 31 additions & 1 deletion ulox/ulox.core.tests/DesugarTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,33 @@ class Foo
Assert.Greater(res.Count, startingCount);
}

[Test]
public void Soa_FooAB_ClassWith2Arrays()
{
var scriptContent = @"
soa FooSoa
{
Foo,
}
";
var (tokens, tokenIterator, context) = Prepare(scriptContent);
var startingCount = tokens.Count;
var res = new List<Token>();
var fooType = new TypeInfoEntry("Foo", UserType.Class);
fooType.AddField("a");
fooType.AddField("b");
context.TypeInfo.AddType(fooType);

AdvanceGather(tokenIterator, res);

Assert.Greater(res.Count, startingCount);
Assert.IsTrue(res.Any(x => x.TokenType == TokenType.CLASS));
Assert.IsTrue(res.Any(x => x.Lexeme == "FooSoa"));
Assert.IsTrue(res.Any(x => x.Lexeme == "a"));
Assert.IsTrue(res.Any(x => x.Lexeme == "b"));
Assert.IsTrue(res.Any(x => x.Lexeme == "Count"));
}

private static (List<Token> tokens, TokenIterator tokenIterator, DummyContext context) Prepare(string scriptContent)
{
var scanner = new Scanner();
Expand Down Expand Up @@ -311,9 +338,12 @@ public class DummyContext : ICompilerDesugarContext
{
public bool IsInClassValue { get; set; }
public HashSet<string> ClassFieldNames { get; set; } = new HashSet<string>();

public TypeInfo TypeInfo { get; set; } = new ();

private int _uniqueNameCount = 0;

public bool DoesClassHaveMatchingField(string x)
public bool DoesCurrentClassHaveMatchingField(string x)
{
return ClassFieldNames.Contains(x);
}
Expand Down
34 changes: 34 additions & 0 deletions ulox/ulox.core.tests/MatchTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,40 @@ match f
Assert.AreEqual("", testEngine.InterpreterResult);
}

[Test]
public void Match_WhenFunRetval_ShouldPass()
{
testEngine.Run(@"
class ShipWeaponCreate
{
GetCreator(name)
{
var localName = name;
match localName
{
""PlayerBullet"" : { retval = ShipWeaponCreate.CreatePlayerBullet; }
""EnemyBullet"" : { retval = ShipWeaponCreate.CreateEnemyBullet; }
}
}
CreatePlayerBullet(ship)
{
BulletSystem.AddBulletFromShip(playerBulletSystemData, ship);
}
CreateEnemyBullet(ship)
{
BulletSystem.AddBulletFromShip(enemyBulletSystemData, ship);
}
}
var retval = ShipWeaponCreate.GetCreator(""PlayerBullet"");
print(retval);
");

StringAssert.StartsWith("<closure CreatePlayerBullet", testEngine.InterpreterResult);
}

[Test]
public void Match_WhenIntWithBody_ShouldPass()
{
Expand Down
Loading

0 comments on commit a33b440

Please sign in to comment.