Skip to content

Commit f8b7fe5

Browse files
committed
- Added support for eval(expr) to evaluate constant expressions to a value
- renamed `lol` files to `yasm` - Added some extra utilities to `lib.yasm`
1 parent 46618a9 commit f8b7fe5

File tree

14 files changed

+140
-38
lines changed

14 files changed

+140
-38
lines changed

YololAssembler/Grammar/AST/BaseDefine.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,36 @@
11
using System.Collections.Generic;
2+
using System.Text.RegularExpressions;
23

34
namespace YololAssembler.Grammar.AST
45
{
56
internal abstract class BaseDefine
67
: BaseStatement
78
{
8-
public abstract string Apply(string input);
9+
public string Apply(string input)
10+
{
11+
var match = Regex.Match(input, FindRegex);
12+
if (!match.Success)
13+
return input;
14+
15+
var r = Replace(match.Groups["body"].Value);
16+
r = Other.Trim(r);
17+
18+
var v = input.Substring(0, match.Index)
19+
+ r
20+
+ input.Substring(0 + match.Index + match.Length);
21+
return v;
22+
}
23+
24+
protected abstract string FindRegex { get; }
25+
26+
protected abstract string Replace(string part);
927

28+
/// <summary>
29+
/// Apply a set of defines repeatedly until fixpoint
30+
/// </summary>
31+
/// <param name="block"></param>
32+
/// <param name="defines"></param>
33+
/// <returns></returns>
1034
internal static string Apply(string block, IEnumerable<BaseDefine> defines)
1135
{
1236
var changed = true;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using Yolol.Execution.Extensions;
3+
using YololAssembler.Grammar.Errors;
4+
5+
namespace YololAssembler.Grammar.AST
6+
{
7+
internal class EvalReplacement
8+
: BaseDefine
9+
{
10+
protected override string FindRegex => $"eval\\((?<body>.*?)\\)";
11+
12+
protected override string Replace(string part)
13+
{
14+
// Convert the floating expression into a statement assigning a variable;
15+
const string name = "_95efe616";
16+
var stmtCode = $"{name}={part}";
17+
18+
// Try to parse this tiny little program
19+
var parsed = Yolol.Grammar.Parser.ParseProgram(stmtCode);
20+
if (!parsed.IsOk)
21+
throw new CannotParseEval(part, parsed.Err);
22+
23+
// Get the parsed expression back out
24+
var stmt = (Yolol.Grammar.AST.Statements.Assignment)parsed.Ok.Lines[0].Statements.Statements[0];
25+
var expr = stmt.Right;
26+
27+
if (!expr.IsConstant)
28+
throw new EvalNotConst(expr);
29+
30+
var v = expr.StaticEvaluate();
31+
32+
if (v.Type == Yolol.Execution.Type.Number)
33+
return v.ToString();
34+
else
35+
return $"\"{v}\"";
36+
}
37+
}
38+
}
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using System.Collections.Generic;
2-
3-
namespace YololAssembler.Grammar.AST
1+
namespace YololAssembler.Grammar.AST
42
{
53
internal class FindAndReplace
64
: BaseDefine
@@ -14,10 +12,11 @@ public FindAndReplace(string identifier, string replacement)
1412
Replacement = replacement;
1513
}
1614

17-
public override string Apply(string input)
15+
protected override string FindRegex => $"(?<body>{Identifier})";
16+
17+
protected override string Replace(string part)
1818
{
19-
var replacement = Other.Trim(Replacement);
20-
return input.Replace($"{Identifier}", replacement);
19+
return Replacement;
2120
}
2221
}
2322
}

YololAssembler/Grammar/AST/FunctionDefine.cs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using System.Text.RegularExpressions;
54

65
namespace YololAssembler.Grammar.AST
76
{
@@ -19,13 +18,11 @@ public FunctionDefine(string identifier, IReadOnlyList<string> arguments, string
1918
Arguments = arguments;
2019
}
2120

22-
public override string Apply(string input)
23-
{
24-
var match = Regex.Match(input, $"{Identifier}\\((.*?)\\)");
25-
if (!match.Success)
26-
return input;
21+
protected override string FindRegex => $"{Identifier}\\((?<body>.*?)\\)";
2722

28-
var parameters = match.Groups[1].Value.Split(",").Where(a => !string.IsNullOrEmpty(a)).ToArray();
23+
protected override string Replace(string part)
24+
{
25+
var parameters = part.Split(",").Where(a => !string.IsNullOrEmpty(a)).ToArray();
2926

3027
if (parameters.Length != Arguments.Count)
3128
throw new InvalidOperationException($"Incorrect number of arguments passed to function `{Identifier}` (expected {Arguments.Count}, got {parameters.Length})");
@@ -41,12 +38,9 @@ public override string Apply(string input)
4138
}
4239

4340
var replacement = Other.Trim(Replacement);
44-
var replaced = BaseDefine.Apply(replacement, defines);
41+
var replaced = Apply(replacement, defines);
4542

46-
var v = input.Substring(0, match.Index)
47-
+ replaced
48-
+ input.Substring(0 + match.Index + match.Length);
49-
return v;
43+
return replaced;
5044
}
5145
}
5246
}

YololAssembler/Grammar/AST/Program.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ public Result Compile(bool compress = true)
2828
// Replace implicit line labels
2929
lines = ApplyImplicitLabels(lines).ToArray();
3030

31+
// Run all `eval` replacements
32+
lines = Apply(new[] { new EvalReplacement() }, lines).ToArray();
33+
3134
// Early out if compression should not be applied
3235
var yolol = string.Join("\n", lines);
3336
if (!compress)
@@ -42,7 +45,7 @@ public Result Compile(bool compress = true)
4245
return new Result(Compress(parsedYolol.Ok));
4346
}
4447

45-
private IEnumerable<string> ApplyImplicitLabels(IEnumerable<string> lines)
48+
private static IEnumerable<string> ApplyImplicitLabels(IEnumerable<string> lines)
4649
{
4750
var lineNum = 1;
4851
foreach (var line in lines)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace YololAssembler.Grammar.Errors
2+
{
3+
public class CannotParseEval
4+
: BaseCompileException
5+
{
6+
public string Expression { get; }
7+
public Yolol.Grammar.Parser.ParseError ParseError { get; }
8+
9+
public CannotParseEval(string expression, Yolol.Grammar.Parser.ParseError parseError)
10+
: base($"Cannot parse expression pass to eval `{expression}`.")
11+
{
12+
Expression = expression;
13+
ParseError = parseError;
14+
}
15+
}
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace YololAssembler.Grammar.Errors
2+
{
3+
public class EvalNotConst
4+
: BaseCompileException
5+
{
6+
public Yolol.Grammar.AST.Expressions.BaseExpression Expression { get; }
7+
8+
public EvalNotConst(Yolol.Grammar.AST.Expressions.BaseExpression expression)
9+
: base($"Expression pass to eval is not constant `{expression}`.")
10+
{
11+
Expression = expression;
12+
}
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
https://go.microsoft.com/fwlink/?LinkID=208121.
4+
-->
5+
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
6+
<PropertyGroup>
7+
<Configuration>Release</Configuration>
8+
<Platform>Any CPU</Platform>
9+
<PublishDir>C:\Users\Martin\Desktop\yasm</PublishDir>
10+
<PublishProtocol>FileSystem</PublishProtocol>
11+
<TargetFramework>netcoreapp3.1</TargetFramework>
12+
<SelfContained>false</SelfContained>
13+
</PropertyGroup>
14+
</Project>

YololAssembler/Scripts/hanoi.lol renamed to YololAssembler/Scripts/hanoi.yasm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#define l_pin_char d
1919
#define r_pin_char e
2020

21-
#import lib.lol
21+
#import lib.yasm
2222

2323
@line1:
2424
b=""

YololAssembler/Scripts/lib.lol

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)