Skip to content
This repository has been archived by the owner on Oct 12, 2024. It is now read-only.

Commit

Permalink
Implemented loops and empty string constants,
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanbeattie committed Jul 9, 2024
1 parent 7cfb871 commit 67c28aa
Show file tree
Hide file tree
Showing 29 changed files with 223 additions and 80 deletions.
6 changes: 6 additions & 0 deletions Starship/Rockstar.Engine/Expressions/CommonVariable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Rockstar.Engine.Expressions;

public class CommonVariable(string name, Source source) : Variable(name, source) {
public CommonVariable(string name) : this(name, Source.None) { }
public override string Key => NormalizedName.ToLowerInvariant();
}
12 changes: 12 additions & 0 deletions Starship/Rockstar.Engine/Expressions/Pronoun.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Text;

namespace Rockstar.Engine.Expressions;

public class Pronoun(string name, Source source) : Variable(name, source) {
public Pronoun() : this(String.Empty) { }
public Pronoun(string name) : this(name, Source.None) { }
public override string Key => Name.ToLowerInvariant();
public override void Print(StringBuilder sb, int depth) {
sb.Indent(depth).AppendLine($"pronoun: {Name}");
}
}
6 changes: 6 additions & 0 deletions Starship/Rockstar.Engine/Expressions/ProperVariable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Rockstar.Engine.Expressions;

public class ProperVariable(string name, Source source) : Variable(name, source) {
public ProperVariable(string name) : this(name, Source.None) { }
public override string Key => NormalizedName.ToUpperInvariant();
}
6 changes: 6 additions & 0 deletions Starship/Rockstar.Engine/Expressions/SimpleVariable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Rockstar.Engine.Expressions;

public class SimpleVariable(string name, Source source) : Variable(name, source) {
public SimpleVariable(string name) : this(name, Source.None) { }
public override string Key => Name.ToLowerInvariant();
}
26 changes: 1 addition & 25 deletions Starship/Rockstar.Engine/Expressions/Variable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,4 @@ protected string NormalizedName
=> String.Join("_", whitespace.Split(Name));

public abstract string Key { get; }
}

public class Pronoun(string name, Source source) : Variable(name, source) {
public Pronoun() : this(String.Empty) { }
public Pronoun(string name) : this(name, Source.None) { }
public override string Key => Name.ToLowerInvariant();
public override void Print(StringBuilder sb, int depth) {
sb.Indent(depth).AppendLine($"pronoun: {Name}");
}
}

public class SimpleVariable(string name, Source source) : Variable(name, source) {
public SimpleVariable(string name) : this(name, Source.None) { }
public override string Key => Name.ToLowerInvariant();
}

public class ProperVariable(string name, Source source) : Variable(name, source) {
public ProperVariable(string name) : this(name, Source.None) { }
public override string Key => NormalizedName.ToUpperInvariant();
}

public class CommonVariable(string name, Source source) : Variable(name, source) {
public CommonVariable(string name) : this(name, Source.None) { }
public override string Key => NormalizedName.ToLowerInvariant();
}
}
16 changes: 11 additions & 5 deletions Starship/Rockstar.Engine/Interpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@

namespace Rockstar.Engine;

public class Result {
public static readonly Result Ok = new();
public static readonly Result Unknown = new();
}

public class Interpreter(RockstarEnvironment env) {

public Result Exec(Block block) {
Expand All @@ -23,9 +18,20 @@ public Result Exec(Block block) {
Conditional cond => Conditional(cond),
Increment inc => Increment(inc),
Decrement dec => Decrement(dec),
Loop loop => Loop(loop),
_ => throw new($"I don't know how to execute {statement.GetType().Name} statements")
};

private Result Loop(Loop loop) {
var result = Result.Unknown;
var condition = Eval(loop.Condition);
while (condition.Truthy == loop.CompareTo) {
result = Exec(loop.Body);
condition = Eval(loop.Condition);
}
return result;
}

private Result Increment(Increment inc) {
return Eval(inc.Variable) switch {
Number n => Assign(inc.Variable, new Number(n.Value + inc.Multiple)),
Expand Down
12 changes: 12 additions & 0 deletions Starship/Rockstar.Engine/PegasusParserExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Text.RegularExpressions;
using Pegasus.Common;

namespace Rockstar.Engine;

public static class PegasusParserExtensions {
public static Source Source(this Cursor cursor, string lexeme = "")
=> new(cursor.Line, cursor.Column, lexeme);

public static string Error(this Cursor cursor, string unexpected)
=> "Unexpected '" + Regex.Escape(unexpected) + "' at line " + cursor.Line + ", col " + (cursor.Column - 1);
}
6 changes: 6 additions & 0 deletions Starship/Rockstar.Engine/Result.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Rockstar.Engine;

public class Result {
public static readonly Result Ok = new();
public static readonly Result Unknown = new();
}
13 changes: 1 addition & 12 deletions Starship/Rockstar.Engine/Source.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using Pegasus.Common;
using System.Text.RegularExpressions;

namespace Rockstar.Engine;

public class Source(int line, int column, string lexeme = "") {
Expand All @@ -9,12 +6,4 @@ public class Source(int line, int column, string lexeme = "") {
$"(line {line}, column {column - lexeme.Length} [{lexeme}])";

public static readonly Source None = new(0, 0, "");
}

public static class PegasusParserExtensions {
public static Source Source(this Cursor cursor, string lexeme = "")
=> new(cursor.Line, cursor.Column, lexeme);

public static string Error(this Cursor cursor, string unexpected)
=> "Unexpected '" + Regex.Escape(unexpected) + "' at line " + cursor.Line + ", col " + (cursor.Column - 1);
}
}
19 changes: 0 additions & 19 deletions Starship/Rockstar.Engine/Statements/Conditional.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,6 @@

namespace Rockstar.Engine.Statements;

public class Increment(Variable v, int multiple, Source source) : Statement(source) {
public Variable Variable => v;
public int Multiple => multiple;
public override void Print(StringBuilder sb, int depth = 0) {
sb.Indent(depth).AppendLine($"increment x {multiple}");
v.Print(sb, depth + 1);
}
}

public class Decrement(Variable v, int multiple, Source source) : Statement(source) {
public Variable Variable => v;
public int Multiple => multiple;
public override void Print(StringBuilder sb, int depth = 0) {
sb.Indent(depth).AppendLine($"decrement x {multiple}");
v.Print(sb, depth + 1);
}
}


public class Conditional(Expression condition, Block consequent, Source source)
: Statement(source) {
public Expression Condition => condition;
Expand Down
13 changes: 13 additions & 0 deletions Starship/Rockstar.Engine/Statements/Decrement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Text;
using Rockstar.Engine.Expressions;

namespace Rockstar.Engine.Statements;

public class Decrement(Variable v, int multiple, Source source) : Statement(source) {
public Variable Variable => v;
public int Multiple => multiple;
public override void Print(StringBuilder sb, int depth = 0) {
sb.Indent(depth).AppendLine($"decrement x {multiple}");
v.Print(sb, depth + 1);
}
}
13 changes: 13 additions & 0 deletions Starship/Rockstar.Engine/Statements/Increment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Text;
using Rockstar.Engine.Expressions;

namespace Rockstar.Engine.Statements;

public class Increment(Variable v, int multiple, Source source) : Statement(source) {
public Variable Variable => v;
public int Multiple => multiple;
public override void Print(StringBuilder sb, int depth = 0) {
sb.Indent(depth).AppendLine($"increment x {multiple}");
v.Print(sb, depth + 1);
}
}
20 changes: 20 additions & 0 deletions Starship/Rockstar.Engine/Statements/Loop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Text;
using Rockstar.Engine.Expressions;
using Rockstar.Engine.Values;

namespace Rockstar.Engine.Statements;

public abstract class Loop(Expression condition, bool compareTo, Block body, Source source)
: Statement(source) {
public bool CompareTo => compareTo;
public Expression Condition => condition;
public Block Body => body;
protected abstract string LoopType { get; }
public override void Print(StringBuilder sb, int depth = 0) {
sb.Indent(depth).AppendLine($"{LoopType}:");
sb.Indent(depth + 1).AppendLine("test:");
condition.Print(sb, depth + 2);
sb.Indent(depth + 1).AppendLine("then:");
body.Print(sb, depth + 2);
}
}
8 changes: 8 additions & 0 deletions Starship/Rockstar.Engine/Statements/UntilLoop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Rockstar.Engine.Expressions;

namespace Rockstar.Engine.Statements;

public class UntilLoop(Expression condition, Block body, Source source)
: Loop(condition, false, body, source) {
protected override string LoopType => "until";
}
8 changes: 8 additions & 0 deletions Starship/Rockstar.Engine/Statements/WhileLoop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Rockstar.Engine.Expressions;

namespace Rockstar.Engine.Statements;

public class WhileLoop(Expression condition, Block body, Source source)
: Loop(condition, true, body, source) {
protected override string LoopType => "while";
}
5 changes: 5 additions & 0 deletions Starship/Rockstar.Engine/Values/IHaveANumber.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Rockstar.Engine.Values;

public interface IHaveANumber {
decimal NumericValue { get; }
}
4 changes: 0 additions & 4 deletions Starship/Rockstar.Engine/Values/Number.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
using System.Text;
namespace Rockstar.Engine.Values;

public interface IHaveANumber {
decimal NumericValue { get; }
}

public class Number(decimal value, Source source)
: Value(source), IHaveANumber {

Expand Down
9 changes: 9 additions & 0 deletions Starship/Rockstar.Engine/Values/Strïng.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@ public override void Print(StringBuilder sb, int depth)
public static readonly Strïng False = new("false");
public static readonly Strïng Null = new("null");
public static readonly Strïng Mysterious = new("mysterious");
public static readonly Strïng Empty = new(String.Empty);

private Strïng(IEnumerable<string> strings)
: this(String.Join("", strings)) { }

public Value Concat(Value that)
=> new Strïng(this.Value + that.ToStrïng().Value);

public Value Repeat(IHaveANumber n)
=> new Strïng(Enumerable
.Range(0, (int) n.NumericValue)
.Select(_ => this.Value));
}
11 changes: 9 additions & 2 deletions Starship/Rockstar.Engine/Values/Value.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,14 @@ public abstract class Value(Source source)
public Value Or(Value that) => this.Truthy ? this : that;

public Value Plus(Value that) => (this, that) switch {
(Number a, Number b) => new Number(a.Value + b.Value),
(Strïng a, _) => a.Concat(that),
(_, Strïng b) => this.ToStrïng().Concat(b),
(IHaveANumber a, IHaveANumber b)
=> new Number(a.NumericValue + b.NumericValue),
(IHaveANumber a, _)
=> Decimal.TryParse(that.ToStrïng().Value, out var d)
? new Number(a.NumericValue + d)
: throw Boom(nameof(Plus), this, that),
_ => throw Boom(nameof(Plus), this, that)
};

Expand Down Expand Up @@ -43,7 +49,8 @@ public override void Print(StringBuilder sb, int depth)
public Value Times(Value that) => (this, that) switch {
(IHaveANumber a, IHaveANumber b)
=> new Number(a.NumericValue * b.NumericValue),
_ => throw new NotImplementedException()
(Strïng s, IHaveANumber n) => s.Repeat(n),
_ => Mysterious.Instance
};

public Value Divide(Value that) => (this, that) switch {
Expand Down
21 changes: 16 additions & 5 deletions Starship/Rockstar.Engine/rockstar.peg
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ EOF = !.
#error{ $"Unexpected '{Regex.Escape(unexpected)}' at line {state.Line}, col {state.Column - 1}" }

statement <Statement>
= alternate
= loop
/ alternate
/ output_stmt
/ assign_stmt
/ increment
Expand All @@ -58,15 +59,21 @@ decrement <Decrement>
{ new Decrement(v, t.Count, state.Source()) }

alternate <Conditional>
= c:conditional (_ / EOS) 'else' a:bonglit
= c:conditional (_ / EOS) 'else' a:body
{ c.Else(a) }
/ c:conditional { c }

conditional <Conditional>
= 'if' _ e:expression a:bonglit
= 'if' _ e:expression a:body
{ new Conditional(e, a, state.Source()) }

bonglit <Block>
loop <Loop>
= 'while' _ e:expression b:body
{ new WhileLoop(e, b, state.Source()) }
/ 'until' _ e:expression b:body
{ new UntilLoop(e, b, state.Source()) }

body <Block>
= EOS b:block
{ b }
/ _ s:statement
Expand Down Expand Up @@ -137,7 +144,7 @@ common_prefix
= ('an' / 'a' / 'the' / 'my' / 'your' / 'our') !letter

simple_variable
= !keyword ("" letter+)
= !keyword ("" letter (letter / [0-9])*)

letter
= uppercase_letter / lowercase_letter
Expand Down Expand Up @@ -248,6 +255,10 @@ constant <Expression>
/ f:false { new Booleän(false, state.Source(f)) }
/ n:null { new Null(state.Source(n)) }
/ m:'mysterious' { Mysterious.Instance }
/ e:empty { Strïng.Empty }

empty
= ('empty'i / 'silent'i / 'silence'i)

true
= ("true" / "yes" / "ok" / "right") !letter
Expand Down
Loading

0 comments on commit 67c28aa

Please sign in to comment.