Skip to content

Commit

Permalink
- Added support for eval(expr) to evaluate constant expressions to …
Browse files Browse the repository at this point in the history
…a value

 - renamed `lol` files to `yasm`
 - Added some extra utilities to `lib.yasm`
  • Loading branch information
martindevans committed Nov 7, 2020
1 parent 46618a9 commit f8b7fe5
Show file tree
Hide file tree
Showing 14 changed files with 140 additions and 38 deletions.
26 changes: 25 additions & 1 deletion YololAssembler/Grammar/AST/BaseDefine.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace YololAssembler.Grammar.AST
{
internal abstract class BaseDefine
: BaseStatement
{
public abstract string Apply(string input);
public string Apply(string input)
{
var match = Regex.Match(input, FindRegex);
if (!match.Success)
return input;

var r = Replace(match.Groups["body"].Value);
r = Other.Trim(r);

var v = input.Substring(0, match.Index)
+ r
+ input.Substring(0 + match.Index + match.Length);
return v;
}

protected abstract string FindRegex { get; }

protected abstract string Replace(string part);

/// <summary>
/// Apply a set of defines repeatedly until fixpoint
/// </summary>
/// <param name="block"></param>
/// <param name="defines"></param>
/// <returns></returns>
internal static string Apply(string block, IEnumerable<BaseDefine> defines)
{
var changed = true;
Expand Down
38 changes: 38 additions & 0 deletions YololAssembler/Grammar/AST/EvalReplacement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using Yolol.Execution.Extensions;
using YololAssembler.Grammar.Errors;

namespace YololAssembler.Grammar.AST
{
internal class EvalReplacement
: BaseDefine
{
protected override string FindRegex => $"eval\\((?<body>.*?)\\)";

protected override string Replace(string part)
{
// Convert the floating expression into a statement assigning a variable;
const string name = "_95efe616";
var stmtCode = $"{name}={part}";

// Try to parse this tiny little program
var parsed = Yolol.Grammar.Parser.ParseProgram(stmtCode);
if (!parsed.IsOk)
throw new CannotParseEval(part, parsed.Err);

// Get the parsed expression back out
var stmt = (Yolol.Grammar.AST.Statements.Assignment)parsed.Ok.Lines[0].Statements.Statements[0];
var expr = stmt.Right;

if (!expr.IsConstant)
throw new EvalNotConst(expr);

var v = expr.StaticEvaluate();

if (v.Type == Yolol.Execution.Type.Number)
return v.ToString();
else
return $"\"{v}\"";
}
}
}
11 changes: 5 additions & 6 deletions YololAssembler/Grammar/AST/FindAndReplace.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Collections.Generic;

namespace YololAssembler.Grammar.AST
namespace YololAssembler.Grammar.AST
{
internal class FindAndReplace
: BaseDefine
Expand All @@ -14,10 +12,11 @@ public FindAndReplace(string identifier, string replacement)
Replacement = replacement;
}

public override string Apply(string input)
protected override string FindRegex => $"(?<body>{Identifier})";

protected override string Replace(string part)
{
var replacement = Other.Trim(Replacement);
return input.Replace($"{Identifier}", replacement);
return Replacement;
}
}
}
18 changes: 6 additions & 12 deletions YololAssembler/Grammar/AST/FunctionDefine.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace YololAssembler.Grammar.AST
{
Expand All @@ -19,13 +18,11 @@ public FunctionDefine(string identifier, IReadOnlyList<string> arguments, string
Arguments = arguments;
}

public override string Apply(string input)
{
var match = Regex.Match(input, $"{Identifier}\\((.*?)\\)");
if (!match.Success)
return input;
protected override string FindRegex => $"{Identifier}\\((?<body>.*?)\\)";

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

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

var replacement = Other.Trim(Replacement);
var replaced = BaseDefine.Apply(replacement, defines);
var replaced = Apply(replacement, defines);

var v = input.Substring(0, match.Index)
+ replaced
+ input.Substring(0 + match.Index + match.Length);
return v;
return replaced;
}
}
}
5 changes: 4 additions & 1 deletion YololAssembler/Grammar/AST/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public Result Compile(bool compress = true)
// Replace implicit line labels
lines = ApplyImplicitLabels(lines).ToArray();

// Run all `eval` replacements
lines = Apply(new[] { new EvalReplacement() }, lines).ToArray();

// Early out if compression should not be applied
var yolol = string.Join("\n", lines);
if (!compress)
Expand All @@ -42,7 +45,7 @@ public Result Compile(bool compress = true)
return new Result(Compress(parsedYolol.Ok));
}

private IEnumerable<string> ApplyImplicitLabels(IEnumerable<string> lines)
private static IEnumerable<string> ApplyImplicitLabels(IEnumerable<string> lines)
{
var lineNum = 1;
foreach (var line in lines)
Expand Down
16 changes: 16 additions & 0 deletions YololAssembler/Grammar/Errors/CannotParseEval.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace YololAssembler.Grammar.Errors
{
public class CannotParseEval
: BaseCompileException
{
public string Expression { get; }
public Yolol.Grammar.Parser.ParseError ParseError { get; }

public CannotParseEval(string expression, Yolol.Grammar.Parser.ParseError parseError)
: base($"Cannot parse expression pass to eval `{expression}`.")
{
Expression = expression;
ParseError = parseError;
}
}
}
14 changes: 14 additions & 0 deletions YololAssembler/Grammar/Errors/EvalNotConst.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace YololAssembler.Grammar.Errors
{
public class EvalNotConst
: BaseCompileException
{
public Yolol.Grammar.AST.Expressions.BaseExpression Expression { get; }

public EvalNotConst(Yolol.Grammar.AST.Expressions.BaseExpression expression)
: base($"Expression pass to eval is not constant `{expression}`.")
{
Expression = expression;
}
}
}
14 changes: 14 additions & 0 deletions YololAssembler/Properties/PublishProfiles/FolderProfile.pubxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>C:\Users\Martin\Desktop\yasm</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<TargetFramework>netcoreapp3.1</TargetFramework>
<SelfContained>false</SelfContained>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#define l_pin_char d
#define r_pin_char e

#import lib.lol
#import lib.yasm

@line1:
b=""
Expand Down
6 changes: 0 additions & 6 deletions YololAssembler/Scripts/lib.lol

This file was deleted.

13 changes: 13 additions & 0 deletions YololAssembler/Scripts/lib.yasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#define undefined _

#define err_if_not(expr) undefined/=expr
#define continue_if(expr) undefined/=expr

#define pop_char(stack) stack---stack
#define push_char(stack, c) stack+=c

#define dequeue_char(q) q---q
#define enqueue_char(q, c) q=c+q

#define set_add_char(set, c) set+=c
#define set_find_char(set, c) set-c!=set
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#define tmp h
#define output :o

#import lib.lol
#import lib.yasm

#define try_next_run_char() {
char2=pop_char(input);
Expand All @@ -31,7 +31,7 @@
ifinput>0then
try_next_run_char()
end
gotofind_run_end+(input<0)*(run_ended_no_chars-find_run_end)
gotofind_run_end+(input<0)*eval(run_ended_no_chars-find_run_end)

@run_ended_dif_char:
output=((delimiter+run_acc+delimiter)-".1.")
Expand Down
7 changes: 0 additions & 7 deletions YololAssembler/Scripts/test.yolol

This file was deleted.

4 changes: 2 additions & 2 deletions YololAssembler/YololAssembler.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
</ItemGroup>

<ItemGroup>
<None Update="Scripts\lib.lol">
<None Update="Scripts\lib.yasm">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Scripts\hanoi.lol">
<None Update="Scripts\hanoi.yasm">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Scripts\test.lol">
Expand Down

0 comments on commit f8b7fe5

Please sign in to comment.