diff --git a/src/Lex.cs b/src/Lex.cs index bd43c7e..56a47e2 100644 --- a/src/Lex.cs +++ b/src/Lex.cs @@ -76,11 +76,13 @@ namespace Dungeoneer.Interpreter { } + /** convenience object class for tokenized input */ public class TokenSet : List { public TokenSet() : base() { } public TokenSet(List set) : base(set) { } + /** returns the first token in the set and removes it. */ public Token Pop() { Token output = this[0]; RemoveAt(0); @@ -102,20 +104,24 @@ namespace Dungeoneer.Interpreter { } + /** a token that contains a value. */ public abstract class DataToken : Token { public T Value { get; protected set; } } + /** a token that is ignored during arithmetic evaluation. */ public abstract class MetadataToken : DataToken { public T Value { get; protected set; } } + /** a token with a numerical value */ public abstract class ValueToken : DataToken { public override string ToString() { return Value.ToString(); } } + /** a token with a string value */ public abstract class StringToken : DataToken { private const string Style = "\x1b[92m"; @@ -129,6 +135,7 @@ namespace Dungeoneer.Interpreter { } + /** a token representing an arithmetic operator. */ public class OperatorToken : DataToken { public OperatorToken(char op) { Value = op; } @@ -137,6 +144,7 @@ namespace Dungeoneer.Interpreter { } + /** a token representing a numeric literal */ public class NumberToken : ValueToken { internal static readonly Regex Pattern = new Regex(@"^(\d+)$"); @@ -147,8 +155,7 @@ namespace Dungeoneer.Interpreter { } - public class NameToken : Token { - public string Value { get; private set; } + public class NameToken : DataToken { internal static readonly Regex Pattern = new Regex(@"^[A-Za-z][A-Za-z\d\-_]+$"); diff --git a/src/Roll.cs b/src/Roll.cs index dbc625a..bb9c3af 100644 --- a/src/Roll.cs +++ b/src/Roll.cs @@ -37,7 +37,7 @@ namespace Dungeoneer { } } - string message = success ? $"{Format.Green}pass" : "{Format.Red}fail"; + string message = success ? $"{Format.Green}pass" : $"{Format.Red}fail"; Console.WriteLine($"{dicePool} > {target}\n => {message}{Format.Reset}"); } diff --git a/src/Scripting.cs b/src/Scripting.cs index 95bf013..9b4526f 100644 --- a/src/Scripting.cs +++ b/src/Scripting.cs @@ -19,36 +19,51 @@ namespace Dungeoneer { Scope = Engine.CreateScope(); dynamic builtin = Engine.GetBuiltinModule(); - // set up imports - var paths = Engine.GetSearchPaths(); - paths.Add("/usr/lib/python3.12/"); - Engine.SetSearchPaths(paths); - // set up python environment - builtin.SetVariable("input", (Func)Input); - builtin.RemoveVariable("open"); + builtin.SetVariable("input", (Func)Input); // `input` in IP is broken; swap for our implementation + builtin.RemoveVariable("open"); // remove 'open' builtin; don't trust scripts with file i/o // helper vars - Scope.repl_commands = Program.ReplCommands; - Scope.roll_macros = Program.RollMacros; + Scope.repl_commands = Program.ReplCommands; // repl command dictionary + Scope.roll_macros = Program.RollMacros; // roll macro dictionary + // interpreter api object Scope.interpret = new ExpandoObject(); Scope.interpret.tokenize = (Func)Lexer.Tokenize; + Scope.interpret.input = (Func)LexInput; Scope.interpret.first_token = (Func)Lexer.First; - // Scope.interpret.parse_roll = (Func)Interpreter.Parser.ParseRoll; + Scope.interpret.parse_roll = (Func)Interpreter.Parser.ParseRoll; // helper functions Scope.roll = (Func)Dungeoneer.Util.Roll; } + /** Executes a Python file. */ public static void Run(string file) { Engine.ExecuteFile(file, Scope); } - public static dynamic Expr(string expression) { return Engine.Execute(expression, Scope); } + /** used for the python interpreter repl. don't use this!!! */ + public static dynamic Expression(string input) { return Engine.Execute(input, Scope); } + + /** + * reimplementation of the Python builtin `input`. + * the default builtin doesn't work correctly. + * + */ public static string Input(string prompt) { Console.Write(prompt); return Console.ReadLine(); } + /** + * implementation of the `interpret.input` helper object method. tokenizes + * the result of the `input` builtin. + * + */ + public static TokenSet LexInput(string prompt) { + var input = Input(prompt); + return Interpreter.Lexer.Tokenize(input); + } + } }