├── Samples ├── Moddable │ ├── Moddable │ │ ├── mods.txt │ │ ├── Icon.ico │ │ ├── mods │ │ │ └── GameMod.dll │ │ ├── Content │ │ │ ├── Owl_Small.png │ │ │ ├── Content.mgcb │ │ │ └── font.spritefont │ │ ├── app.config │ │ ├── packages.config │ │ ├── IGameState.cs │ │ ├── Program.cs │ │ ├── PlayerSelect.cs │ │ ├── PlayState.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── app.manifest │ │ ├── Player.cs │ │ ├── SelectState.cs │ │ └── Game1.cs │ ├── ModdableExtern │ │ ├── packages.config │ │ ├── Input.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ └── ModdableExtern.csproj │ ├── GameBase │ │ ├── build.cfg │ │ └── player.tfs │ ├── GameMod │ │ ├── build.cfg │ │ └── inverted.tfs │ └── Moddable.sln ├── TestSuite │ ├── Tests │ │ ├── nop.tfs │ │ ├── build.cfg │ │ ├── ternary.tfs │ │ ├── script_composition.tfs │ │ ├── return.tfs │ │ ├── tests.tfs │ │ ├── object_import.tfs │ │ ├── repeat.tfs │ │ ├── with.tfs │ │ ├── lambda.tfs │ │ ├── math.tfs │ │ ├── map.tfs │ │ └── struct.tfs │ ├── UnitTestLib │ │ ├── test_imports.tfs │ │ ├── build.cfg │ │ └── unit_test.tfs │ └── TaffyScript.Tests │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── TaffyScript.Tests.csproj │ │ └── TestHelper.cs ├── HelloLanguage │ ├── build.cfg │ ├── trace.tfs │ └── source.tfs └── Threading │ ├── TaffyScript.Threading.Tests │ ├── build.cfg │ └── threading_tests.tfs │ └── TaffyScript.Threading │ ├── Locks.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── TaffyScript.Threading.csproj │ ├── Tasks.cs │ └── ThreadLock.cs ├── docs ├── _config.yml └── index.html ├── TaffyScript.CommandLine ├── packages.config ├── App.config ├── Properties │ └── AssemblyInfo.cs ├── ErrorLogger.cs ├── TaffyScript.CommandLine.csproj └── Program.cs ├── TaffyScript.Compiler ├── Syntax │ ├── ISyntaxToken.cs │ ├── ISyntaxNode.cs │ ├── ConstantType.cs │ ├── Concrete │ │ ├── ImportObject │ │ │ ├── ImportCasing.cs │ │ │ ├── ImportObjectConstructor.cs │ │ │ ├── ImportObjectField.cs │ │ │ └── ImportObjectMethod.cs │ │ ├── EndToken.cs │ │ ├── BreakToken.cs │ │ ├── RootNode.cs │ │ ├── ContinueToken.cs │ │ ├── BlockNode.cs │ │ ├── ReadOnlyToken.cs │ │ ├── ReturnNode.cs │ │ ├── VariableToken.cs │ │ ├── LocalsNode.cs │ │ ├── ArgumentAccessNode.cs │ │ ├── ArrayLiteralNode.cs │ │ ├── PostfixNode.cs │ │ ├── PrefixNode.cs │ │ ├── EnumNode.cs │ │ ├── DoNode.cs │ │ ├── RepeatNode.cs │ │ ├── WithNode.cs │ │ ├── WhileNode.cs │ │ ├── MemberAccessNode.cs │ │ ├── NamespaceNode.cs │ │ ├── ArrayAccessNode.cs │ │ ├── UsingsNode.cs │ │ ├── ShiftNode.cs │ │ ├── AssignNode.cs │ │ ├── BitwiseNode.cs │ │ ├── LogicalNode.cs │ │ ├── AdditiveNode.cs │ │ ├── EqualityNode.cs │ │ ├── RelationalNode.cs │ │ ├── MultiplicativeNode.cs │ │ ├── ObjectNode.cs │ │ ├── ScriptNode.cs │ │ ├── ConstantToken.cs │ │ ├── ConditionalNode.cs │ │ ├── IfNode.cs │ │ ├── BaseNode.cs │ │ ├── LambdaNode.cs │ │ ├── NewNode.cs │ │ ├── FunctionCallNode.cs │ │ ├── ForNode.cs │ │ ├── SwitchNode.cs │ │ └── ImportScriptNode.cs │ ├── IConstantToken.cs │ ├── Containers │ │ ├── EnumValue.cs │ │ ├── SwitchCase.cs │ │ ├── UsingDeclaration.cs │ │ └── VariableDeclaration.cs │ ├── ISyntaxElement.cs │ ├── SyntaxNode.cs │ ├── SyntaxToken.cs │ ├── SyntaxType.cs │ └── ISyntaxElementVisitor.cs ├── App.config ├── Symbols │ ├── ISymbol.cs │ ├── SymbolScope.cs │ ├── SymbolType.cs │ ├── ObjectSymbol.cs │ ├── EnumLeaf.cs │ ├── VariableLeaf.cs │ ├── InvalidSymbolException.cs │ ├── ImportLeaf.cs │ ├── SymbolLeaf.cs │ ├── ImportObjectLeaf.cs │ └── SymbolNode.cs ├── Backend │ ├── CompileMode.cs │ ├── ImportType.cs │ ├── Compiler │ │ ├── ICompiler.cs │ │ ├── CompileException.cs │ │ ├── Closure.cs │ │ └── TypeEqualityComparer.cs │ ├── NameConflictException.cs │ ├── BuildConfig.cs │ └── CompilerResult.cs ├── Front End │ ├── ParseException.cs │ └── LexicalAnalysis │ │ ├── Token.cs │ │ ├── TokenPosition.cs │ │ └── TokenType.cs ├── IErrorLogger.cs ├── Properties │ └── AssemblyInfo.cs ├── StringUtils.cs ├── DotNet │ └── AssemblyLoader.cs └── SymbolResolver.cs ├── TaffyScript ├── Exceptions │ ├── UserDefinedException.cs │ ├── InvalidInstanceException.cs │ ├── InvalidTsTypeException.cs │ └── MemberAccessException.cs ├── Attributes │ ├── WeakBaseTypeAttribute.cs │ ├── WeakObjectAttribute.cs │ ├── WeakMethodAttribute.cs │ └── WeakLibraryAttribute.cs ├── ObjectWrapper.cs ├── VariableType.cs ├── ObjectDefinition.cs ├── TaffyScriptLoader.cs ├── Extensions.cs ├── Collections │ └── EventCache.cs ├── Properties │ └── AssemblyInfo.cs ├── TsValue.cs ├── TsInstance.cs ├── DynamicInstance.cs ├── ITsInstance.cs ├── TaffyScript.csproj └── TsDelegate.cs ├── LICENSE ├── .gitattributes └── README.md /Samples/Moddable/Moddable/mods.txt: -------------------------------------------------------------------------------- 1 | GameMod -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-merlot -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 |

Hello, TaffyScript

2 | -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/nop.tfs: -------------------------------------------------------------------------------- 1 | namespace LanguageTests { 2 | script nop { 3 | 4 | } 5 | } -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mystborn/TaffyScript/HEAD/Samples/Moddable/Moddable/Icon.ico -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/mods/GameMod.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mystborn/TaffyScript/HEAD/Samples/Moddable/Moddable/mods/GameMod.dll -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/Content/Owl_Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mystborn/TaffyScript/HEAD/Samples/Moddable/Moddable/Content/Owl_Small.png -------------------------------------------------------------------------------- /TaffyScript.CommandLine/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/ISyntaxToken.cs: -------------------------------------------------------------------------------- 1 | namespace TaffyScript.Compiler.Syntax 2 | { 3 | public interface ISyntaxToken : ISyntaxElement 4 | { 5 | string Name { get; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Samples/Moddable/ModdableExtern/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /TaffyScript.CommandLine/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /TaffyScript/Exceptions/UserDefinedException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TaffyScript 4 | { 5 | public class UserDefinedException : Exception 6 | { 7 | public UserDefinedException(string message) 8 | : base(message) 9 | { 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Samples/TestSuite/UnitTestLib/test_imports.tfs: -------------------------------------------------------------------------------- 1 | namespace UnitTest { 2 | import TestHelper.Try(instance, array) as try; 3 | import TestHelper.TryExpect(instance, array) as try_expect; 4 | import TestHelper.CollectGarbage() as gc_collect; 5 | import TestHelper.TimeInvoke(instance, array) as time_invoke; 6 | } -------------------------------------------------------------------------------- /TaffyScript/Exceptions/InvalidInstanceException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript 8 | { 9 | public class InvalidInstanceException : Exception 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/ISyntaxNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public interface ISyntaxNode : ISyntaxElement 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Symbols/ISymbol.cs: -------------------------------------------------------------------------------- 1 | namespace TaffyScript.Compiler 2 | { 3 | public interface ISymbol 4 | { 5 | SymbolType Type { get; } 6 | SymbolScope Scope { get; } 7 | string Name { get; } 8 | bool IsLeaf { get; } 9 | SymbolNode Parent { get; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Backend/CompileMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Backend 8 | { 9 | public enum CompileMode 10 | { 11 | Debug, 12 | Release 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Samples/HelloLanguage/build.cfg: -------------------------------------------------------------------------------- 1 | 2 | 3 | bin\HelloLanguage 4 | 5 | TaffyScript.BCL.dll 6 | 7 | Debug 8 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Backend/ImportType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Backend 8 | { 9 | public enum ImportType : byte 10 | { 11 | Script, 12 | Object 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Symbols/SymbolScope.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler 8 | { 9 | public enum SymbolScope 10 | { 11 | Local, 12 | Member, 13 | Global 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/ConstantType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler 8 | { 9 | public enum ConstantType 10 | { 11 | Bool, 12 | Real, 13 | String 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /TaffyScript/Attributes/WeakBaseTypeAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TaffyScript 4 | { 5 | /// 6 | /// Tags a type as a TaffyScript base type. 7 | /// 8 | public class WeakBaseTypeAttribute : Attribute 9 | { 10 | public WeakBaseTypeAttribute() 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Backend/Compiler/ICompiler.cs: -------------------------------------------------------------------------------- 1 | namespace TaffyScript.Compiler.Backend 2 | { 3 | public interface ICompiler 4 | { 5 | CompilerResult CompileProject(string projectDir); 6 | CompilerResult CompileCode(string code, BuildConfig config); 7 | CompilerResult CompileCode(string code, string output); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /TaffyScript/ObjectWrapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript 8 | { 9 | public abstract class ObjectWrapper 10 | { 11 | protected Dictionary _members = new Dictionary(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ImportObject/ImportCasing.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public enum ImportCasing 10 | { 11 | Native, 12 | Camel, 13 | Pascal, 14 | Snake 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /TaffyScript/VariableType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript 8 | { 9 | public enum VariableType 10 | { 11 | Null, 12 | Real, 13 | String, 14 | Array1, 15 | Array2, 16 | Delegate, 17 | Instance 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Symbols/SymbolType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler 8 | { 9 | public enum SymbolType 10 | { 11 | Block, 12 | Object, 13 | Enum, 14 | Script, 15 | Namespace, 16 | Variable 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TaffyScript/Attributes/WeakObjectAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TaffyScript 4 | { 5 | /// 6 | /// Tags an object as a weak TaffyScript object. 7 | /// 8 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 9 | public class WeakObjectAttribute : Attribute 10 | { 11 | public WeakObjectAttribute() 12 | { 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /TaffyScript.Compiler/Front End/ParseException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TaffyScript.Compiler.FrontEnd 4 | { 5 | public class ParseException : Exception 6 | { 7 | public ParseException() : base() { } 8 | public ParseException(string message) : base(message) { } 9 | public ParseException(string message, Exception innerException) : base(message, innerException) { } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /TaffyScript/Attributes/WeakMethodAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TaffyScript 4 | { 5 | /// 6 | /// Tags a method as a weak TaffyScript method. 7 | /// 8 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] 9 | public class WeakMethodAttribute : Attribute 10 | { 11 | public WeakMethodAttribute() 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Samples/TestSuite/UnitTestLib/build.cfg: -------------------------------------------------------------------------------- 1 | 2 | 3 | bin\UnitTest 4 | 5 | TaffyScript.BCL.dll 6 | ..\TaffyScript.Tests\bin\Release\TaffyScript.Tests.dll 7 | 8 | Release 9 | -------------------------------------------------------------------------------- /TaffyScript/Attributes/WeakLibraryAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TaffyScript 4 | { 5 | /// 6 | /// Tags an assembly as a weak TaffyScript assembly. 7 | /// 8 | [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] 9 | public class WeakLibraryAttribute : Attribute 10 | { 11 | public WeakLibraryAttribute() 12 | { 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Samples/HelloLanguage/trace.tfs: -------------------------------------------------------------------------------- 1 | //Empty file... 2 | namespace HelloLanguage { 3 | script trace { 4 | if(argument_count == 0) { 5 | show_debug_message(""); 6 | exit; 7 | } 8 | var output = string(argument[0]); 9 | for(var i = 1; i < argument_count; i++) { 10 | output += ", " + string(argument[i]); 11 | } 12 | show_debug_message(output); 13 | } 14 | } -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/IGameState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Microsoft.Xna.Framework; 7 | using Microsoft.Xna.Framework.Graphics; 8 | 9 | namespace Moddable 10 | { 11 | public interface IGameState 12 | { 13 | void Draw(SpriteBatch batch); 14 | void Update(GameTime gameTime); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Backend/Compiler/CompileException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Backend 8 | { 9 | public class CompileException : Exception 10 | { 11 | public CompileException(string message) 12 | : base(message) 13 | { 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Backend/NameConflictException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Backend 8 | { 9 | public class NameConflictException : Exception 10 | { 11 | public NameConflictException(string message) 12 | : base(message) 13 | { 14 | 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Samples/Moddable/GameBase/build.cfg: -------------------------------------------------------------------------------- 1 | 2 | 3 | bin\GameBase 4 | 5 | TaffyScript.BCL.dll 6 | References\Monogame.Framework.dll 7 | References\ModdableExtern.dll 8 | 9 | Debug 10 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Symbols/ObjectSymbol.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler 8 | { 9 | public class ObjectSymbol : SymbolNode 10 | { 11 | public ISymbol Inherits { get; set; } 12 | 13 | public ObjectSymbol(SymbolNode parent, string name) 14 | : base(parent, name, SymbolType.Object) 15 | { 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/IConstantToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public interface IConstantToken : ISyntaxToken 10 | { 11 | ConstantType ConstantType { get; } 12 | object WeakValue { get; } 13 | } 14 | 15 | public interface IConstantToken : IConstantToken 16 | { 17 | T Value { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Samples/Moddable/GameMod/build.cfg: -------------------------------------------------------------------------------- 1 | 2 | 3 | bin\GameMod 4 | 5 | TaffyScript.BCL.dll 6 | References\Monogame.Framework.dll 7 | References\ModdableExtern.dll 8 | ..\GameBase\bin\GameBase.dll 9 | 10 | Debug 11 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Containers/EnumValue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public struct EnumValue 10 | { 11 | public string Name { get; } 12 | public long Value { get; } 13 | 14 | public EnumValue(string name, long value) 15 | { 16 | Name = name; 17 | Value = value; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Moddable 4 | { 5 | #if WINDOWS || LINUX 6 | /// 7 | /// The main class. 8 | /// 9 | public static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | using (var game = new Game1()) 18 | game.Run(); 19 | } 20 | } 21 | #endif 22 | } 23 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Symbols/EnumLeaf.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler 8 | { 9 | public class EnumLeaf : SymbolLeaf 10 | { 11 | public long Value { get; } 12 | 13 | public EnumLeaf(SymbolNode parent, string name, SymbolType type, SymbolScope scope, long value) : base(parent, name, type, scope) 14 | { 15 | Value = value; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Symbols/VariableLeaf.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler 8 | { 9 | public class VariableLeaf : SymbolLeaf 10 | { 11 | public bool IsCaptured { get; set; } = false; 12 | 13 | public VariableLeaf(SymbolNode parent, string name, SymbolScope scope) 14 | : base(parent, name, SymbolType.Variable, scope) 15 | { 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Samples/Threading/TaffyScript.Threading.Tests/build.cfg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | TaffyScript.BCL.dll 5 | ..\TaffyScript.Threading\bin\Release\TaffyScript.Threading.Extern.dll 6 | 7 | bin\TaffyScript.Threading.Tests 8 | TaffyScript.Threading.Tests.main 9 | Debug 10 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/ISyntaxElement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using TaffyScript.Compiler.FrontEnd; 7 | 8 | namespace TaffyScript.Compiler.Syntax 9 | { 10 | public interface ISyntaxElement 11 | { 12 | ISyntaxNode Parent { get; set; } 13 | SyntaxType Type { get; } 14 | TokenPosition Position { get; } 15 | bool IsToken { get; } 16 | 17 | void Accept(ISyntaxElementVisitor visitor); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/IErrorLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler 8 | { 9 | public interface IErrorLogger 10 | { 11 | List Errors { get; } 12 | List Warnings { get; } 13 | void Error(string message); 14 | void Error(string message, TokenPosition position); 15 | void Warning(string message); 16 | void Warning(string message, TokenPosition position); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Containers/SwitchCase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public struct SwitchCase 10 | { 11 | public ISyntaxElement Expression { get; } 12 | public BlockNode Body { get; } 13 | 14 | public SwitchCase(ISyntaxElement expression, BlockNode body) 15 | { 16 | Expression = expression; 17 | Body = body; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/EndToken.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class EndToken : SyntaxToken 6 | { 7 | public override SyntaxType Type => SyntaxType.End; 8 | public override string Name => ";"; 9 | 10 | public EndToken(TokenPosition position) 11 | : base(position) 12 | { 13 | } 14 | 15 | public override void Accept(ISyntaxElementVisitor visitor) 16 | { 17 | visitor.Visit(this); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /TaffyScript/Exceptions/InvalidTsTypeException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript 8 | { 9 | public class InvalidTsTypeException : Exception 10 | { 11 | public InvalidTsTypeException(string message) 12 | : base(message) 13 | { 14 | } 15 | 16 | public InvalidTsTypeException(string message, Exception innerException) 17 | : base(message, innerException) 18 | { 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/BreakToken.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class BreakToken : SyntaxToken 6 | { 7 | public override SyntaxType Type => SyntaxType.Break; 8 | public override string Name => "break"; 9 | 10 | public BreakToken(TokenPosition position) 11 | : base(position) 12 | { 13 | } 14 | 15 | public override void Accept(ISyntaxElementVisitor visitor) 16 | { 17 | visitor.Visit(this); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Symbols/InvalidSymbolException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TaffyScript.Compiler 4 | { 5 | public class InvalidSymbolException : Exception 6 | { 7 | public InvalidSymbolException() 8 | : base() 9 | { 10 | } 11 | 12 | public InvalidSymbolException(string message) 13 | : base(message) 14 | { 15 | } 16 | 17 | public InvalidSymbolException(string message, Exception innerException) 18 | : base(message, innerException) 19 | { 20 | 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/RootNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class RootNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Root; 8 | public List CompilationUnits { get; } = new List(); 9 | 10 | public RootNode() 11 | : base(null) 12 | { 13 | } 14 | 15 | public override void Accept(ISyntaxElementVisitor visitor) 16 | { 17 | visitor.Visit(this); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Containers/UsingDeclaration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public struct UsingDeclaration 10 | { 11 | public string Namespace { get; } 12 | public TokenPosition Position { get; } 13 | 14 | public UsingDeclaration(string nameSpace, TokenPosition position) 15 | { 16 | Namespace = nameSpace; 17 | Position = position; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ContinueToken.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class ContinueToken : SyntaxToken 6 | { 7 | public override SyntaxType Type => SyntaxType.Continue; 8 | public override string Name => "continue"; 9 | 10 | public ContinueToken(TokenPosition position) 11 | : base(position) 12 | { 13 | } 14 | 15 | public override void Accept(ISyntaxElementVisitor visitor) 16 | { 17 | visitor.Visit(this); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Symbols/ImportLeaf.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using TaffyScript.Compiler.Syntax; 7 | 8 | namespace TaffyScript.Compiler 9 | { 10 | public class ImportLeaf : SymbolLeaf 11 | { 12 | public ImportScriptNode Node { get; } 13 | 14 | public ImportLeaf(SymbolNode parent, string name, SymbolScope scope, ImportScriptNode node) 15 | : base(parent, name, SymbolType.Script, scope) 16 | { 17 | Node = node; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Samples/Moddable/GameMod/inverted.tfs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework.Input; 2 | using GameBase; 3 | 4 | namespace GameMod { 5 | object obj_invert_select : par_character_select { 6 | event create { 7 | name = "Inverted"; 8 | player = obj_invert_player; 9 | } 10 | } 11 | 12 | object obj_invert_player : obj_player { 13 | event step { 14 | var hspd = key_check(Keys.Left) - key_check(Keys.Right); 15 | var vspd = key_check(Keys.Up) - key_check(Keys.Down); 16 | x += hspd * speed; 17 | y += vspd * speed; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ImportObject/ImportObjectConstructor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public class ImportObjectConstructor 10 | { 11 | public List Arguments { get; } 12 | public TokenPosition Position { get; } 13 | 14 | public ImportObjectConstructor(List arguments, TokenPosition position) 15 | { 16 | Arguments = arguments; 17 | Position = position; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/BlockNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class BlockNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Block; 8 | public List Body { get; } 9 | 10 | public BlockNode(List body, TokenPosition position) 11 | : base(position) 12 | { 13 | Body = body; 14 | } 15 | 16 | public override void Accept(ISyntaxElementVisitor visitor) 17 | { 18 | visitor.Visit(this); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ReadOnlyToken.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class ReadOnlyToken : SyntaxToken 6 | { 7 | public override SyntaxType Type => SyntaxType.ReadOnly; 8 | public override string Name { get; } 9 | 10 | public ReadOnlyToken(string name, TokenPosition position) 11 | : base(position) 12 | { 13 | Name = name; 14 | } 15 | 16 | public override void Accept(ISyntaxElementVisitor visitor) 17 | { 18 | visitor.Visit(this); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ReturnNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class ReturnNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Return; 8 | public ISyntaxElement Result { get; } 9 | 10 | public ReturnNode(ISyntaxElement result, TokenPosition position) 11 | : base(position) 12 | { 13 | Result = result; 14 | } 15 | 16 | public override void Accept(ISyntaxElementVisitor visitor) 17 | { 18 | visitor.Visit(this); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/VariableToken.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class VariableToken : SyntaxToken 6 | { 7 | public override SyntaxType Type => SyntaxType.Variable; 8 | public override string Name { get; } 9 | 10 | public VariableToken(string name, TokenPosition position) 11 | : base(position) 12 | { 13 | Name = name; 14 | } 15 | 16 | public override void Accept(ISyntaxElementVisitor visitor) 17 | { 18 | visitor.Visit(this); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/build.cfg: -------------------------------------------------------------------------------- 1 | 2 | 3 | bin\tests 4 | 5 | TaffyScript.BCL.dll 6 | ..\TaffyScript.Tests\bin\Release\TaffyScript.Tests.dll 7 | ..\UnitTestLib\bin\UnitTest.dll 8 | 9 | 10 | struct.tfs 11 | 12 | 13 | LanguageTests.main 14 | Debug 15 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/LocalsNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class LocalsNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Locals; 8 | public List Locals { get; } 9 | 10 | public LocalsNode(List locals, TokenPosition position) 11 | : base(position) 12 | { 13 | Locals = locals; 14 | } 15 | 16 | public override void Accept(ISyntaxElementVisitor visitor) 17 | { 18 | visitor.Visit(this); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ArgumentAccessNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class ArgumentAccessNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.ArgumentAccess; 8 | public ISyntaxElement Index { get; } 9 | 10 | public ArgumentAccessNode(ISyntaxElement index, TokenPosition position) 11 | : base(position) 12 | { 13 | Index = index; 14 | } 15 | 16 | public override void Accept(ISyntaxElementVisitor visitor) 17 | { 18 | visitor.Visit(this); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ArrayLiteralNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class ArrayLiteralNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.ArrayLiteral; 8 | public List Elements { get; } 9 | 10 | public ArrayLiteralNode(List elements, TokenPosition position) 11 | : base(position) 12 | { 13 | Elements = elements; 14 | } 15 | 16 | public override void Accept(ISyntaxElementVisitor visitor) 17 | { 18 | visitor.Visit(this); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TaffyScript/Exceptions/MemberAccessException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Exceptions 8 | { 9 | public class MemberAccessException : Exception 10 | { 11 | public MemberAccessException() 12 | : base() 13 | { 14 | } 15 | 16 | public MemberAccessException(string message) 17 | : base(message) 18 | { 19 | } 20 | 21 | public MemberAccessException(string message, Exception innerException) 22 | : base(message, innerException) 23 | { 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/PostfixNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class PostfixNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Postfix; 8 | public ISyntaxElement Left { get; } 9 | public string Op { get; } 10 | 11 | public PostfixNode(ISyntaxElement left, string op, TokenPosition position) 12 | : base(position) 13 | { 14 | Left = left; 15 | Op = op; 16 | } 17 | 18 | public override void Accept(ISyntaxElementVisitor visitor) 19 | { 20 | visitor.Visit(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/PrefixNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class PrefixNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Prefix; 8 | public string Op { get; } 9 | public ISyntaxElement Right { get; } 10 | 11 | public PrefixNode(string op, ISyntaxElement right, TokenPosition position) 12 | : base(position) 13 | { 14 | Op = op; 15 | Right = right; 16 | } 17 | 18 | public override void Accept(ISyntaxElementVisitor visitor) 19 | { 20 | visitor.Visit(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/EnumNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class EnumNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Enum; 8 | public string Name { get; } 9 | public List Values { get; } 10 | 11 | public EnumNode(string name, List values, TokenPosition position) 12 | : base(position) 13 | { 14 | Name = name; 15 | Values = values; 16 | } 17 | 18 | public override void Accept(ISyntaxElementVisitor visitor) 19 | { 20 | visitor.Visit(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ImportObject/ImportObjectField.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public class ImportObjectField 10 | { 11 | public TokenPosition Position { get; } 12 | public string ExternalName { get; } 13 | public string ImportName { get; } 14 | 15 | public ImportObjectField(string externalName, string importName, TokenPosition position) 16 | { 17 | Position = position; 18 | ExternalName = externalName; 19 | ImportName = importName; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/DoNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class DoNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Do; 8 | public ISyntaxElement Body { get; } 9 | public ISyntaxElement Condition { get; } 10 | 11 | public DoNode(ISyntaxElement body, ISyntaxElement condition, TokenPosition position) 12 | : base(position) 13 | { 14 | Body = body; 15 | Condition = condition; 16 | } 17 | 18 | public override void Accept(ISyntaxElementVisitor visitor) 19 | { 20 | visitor.Visit(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/RepeatNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class RepeatNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Repeat; 8 | public ISyntaxElement Count { get; } 9 | public ISyntaxElement Body { get; } 10 | 11 | public RepeatNode(ISyntaxElement count, ISyntaxElement body, TokenPosition position) 12 | : base(position) 13 | { 14 | Count = count; 15 | Body = body; 16 | } 17 | 18 | public override void Accept(ISyntaxElementVisitor visitor) 19 | { 20 | visitor.Visit(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/WithNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class WithNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.With; 8 | public ISyntaxElement Target { get; } 9 | public ISyntaxElement Body { get; } 10 | 11 | public WithNode(ISyntaxElement target, ISyntaxElement body, TokenPosition position) 12 | : base(position) 13 | { 14 | Target = target; 15 | Body = body; 16 | } 17 | 18 | public override void Accept(ISyntaxElementVisitor visitor) 19 | { 20 | visitor.Visit(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Containers/VariableDeclaration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public struct VariableDeclaration 10 | { 11 | public string Name { get; } 12 | public ISyntaxElement Value { get; } 13 | public TokenPosition Position { get; } 14 | public bool HasValue => Value != null; 15 | 16 | public VariableDeclaration(string name, ISyntaxElement value, TokenPosition position) 17 | { 18 | Name = name; 19 | Value = value; 20 | Position = position; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/PlayerSelect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using TaffyScript; 7 | 8 | namespace Moddable 9 | { 10 | public class PlayerSelect 11 | { 12 | private TsInstance _source; 13 | 14 | public string Name => (string)_source["name"]; 15 | public string PlayerObjectType => (string)_source["player"]; 16 | 17 | public PlayerSelect(string typeName) 18 | { 19 | _source = new TsInstance(typeName); 20 | } 21 | 22 | public void Destroy() 23 | { 24 | _source.Destroy(); 25 | _source = null; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Symbols/SymbolLeaf.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TaffyScript.Compiler 4 | { 5 | public class SymbolLeaf : ISymbol 6 | { 7 | public SymbolType Type { get; } 8 | public SymbolScope Scope { get; } 9 | public bool IsLeaf => true; 10 | public string Name { get; } 11 | public SymbolNode Parent { get; } 12 | 13 | public SymbolLeaf(SymbolNode parent, string name, SymbolType type, SymbolScope scope) 14 | { 15 | Parent = parent ?? throw new ArgumentNullException(nameof(parent)); 16 | Name = name ?? throw new ArgumentNullException(nameof(name)); 17 | Type = type; 18 | Scope = scope; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/WhileNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class WhileNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.While; 8 | public ISyntaxElement Condition { get; } 9 | public ISyntaxElement Body { get; } 10 | 11 | public WhileNode(ISyntaxElement condition, ISyntaxElement body, TokenPosition position) 12 | : base(position) 13 | { 14 | Condition = condition; 15 | Body = body; 16 | } 17 | 18 | public override void Accept(ISyntaxElementVisitor visitor) 19 | { 20 | visitor.Visit(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TaffyScript/ObjectDefinition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript 8 | { 9 | public struct ObjectDefinition 10 | { 11 | public string Name; 12 | public string Parent; 13 | public Dictionary Scripts; 14 | public Func Create; 15 | 16 | public ObjectDefinition(string name, string parent, Dictionary scripts, Func create) 17 | { 18 | Name = name; 19 | Parent = parent; 20 | Scripts = scripts; 21 | Create = create; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/MemberAccessNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class MemberAccessNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.MemberAccess; 8 | public ISyntaxElement Left { get; } 9 | public ISyntaxElement Right { get; } 10 | 11 | public MemberAccessNode(ISyntaxElement left, ISyntaxElement right, TokenPosition position) 12 | : base(position) 13 | { 14 | Left = left; 15 | Right = right; 16 | } 17 | 18 | public override void Accept(ISyntaxElementVisitor visitor) 19 | { 20 | visitor.Visit(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/ternary.tfs: -------------------------------------------------------------------------------- 1 | using UnitTest; 2 | 3 | namespace LanguageTests { 4 | script run_ternary_tests() { 5 | var tests = new obj_unit_test("Ternary Tests", 6 | ternary_var_assign, 7 | ternary_argument_assign); 8 | 9 | tests.run_tests(); 10 | } 11 | 12 | script ternary_var_assign() { 13 | test_it("i = bool ? n1 : n2"); 14 | var test = true; 15 | var i = test == true ? 2 : 4; 16 | assert_equal(i, 2); 17 | } 18 | 19 | script ternary_argument_assign() { 20 | test_it("i = argument_count == 0 ? '' : arg0"); 21 | var i = argument_count == 0 ? "moo" : "cow"; 22 | assert_equal(i, "moo"); 23 | } 24 | } -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/NamespaceNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class NamespaceNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Namespace; 8 | public string Name { get; } 9 | public List Declarations { get; } 10 | 11 | public NamespaceNode(string name, List declarations, TokenPosition position) 12 | : base(position) 13 | { 14 | Name = name; 15 | Declarations = declarations; 16 | } 17 | 18 | public override void Accept(ISyntaxElementVisitor visitor) 19 | { 20 | visitor.Visit(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ArrayAccessNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class ArrayAccessNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.ArrayAccess; 8 | public ISyntaxElement Left { get; } 9 | public List Arguments { get; } 10 | 11 | public ArrayAccessNode(ISyntaxElement left, List arguments, TokenPosition position) 12 | : base(position) 13 | { 14 | Left = left; 15 | Arguments = arguments; 16 | } 17 | 18 | public override void Accept(ISyntaxElementVisitor visitor) 19 | { 20 | visitor.Visit(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Backend/Compiler/Closure.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Reflection; 7 | using System.Reflection.Emit; 8 | 9 | namespace TaffyScript.Compiler.Backend 10 | { 11 | public class Closure 12 | { 13 | public TypeBuilder Type { get; } 14 | public ConstructorBuilder Constructor { get; set; } 15 | public Dictionary Fields { get; set; } = new Dictionary(); 16 | public LocalBuilder Self { get; set; } = null; 17 | 18 | public Closure(TypeBuilder type, ConstructorBuilder ctor) 19 | { 20 | Type = type; 21 | Constructor = ctor; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/UsingsNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class UsingsNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Usings; 8 | public List Usings { get; } 9 | public List Declarations { get; } 10 | 11 | public UsingsNode(List usings, List declarations, TokenPosition position) 12 | : base(position) 13 | { 14 | Usings = usings; 15 | Declarations = declarations; 16 | } 17 | 18 | public override void Accept(ISyntaxElementVisitor visitor) 19 | { 20 | visitor.Visit(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ShiftNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class ShiftNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Shift; 8 | public ISyntaxElement Left { get; } 9 | public string Op { get; } 10 | public ISyntaxElement Right { get; } 11 | 12 | public ShiftNode(ISyntaxElement left, string op, ISyntaxElement right, TokenPosition position) 13 | : base(position) 14 | { 15 | Left = left; 16 | Op = op; 17 | Right = right; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/AssignNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class AssignNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Assign; 8 | public ISyntaxElement Left { get; } 9 | public string Op { get; } 10 | public ISyntaxElement Right { get; } 11 | 12 | public AssignNode(ISyntaxElement left, string op, ISyntaxElement right, TokenPosition position) 13 | : base(position) 14 | { 15 | Left = left; 16 | Op = op; 17 | Right = right; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/BitwiseNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class BitwiseNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Bitwise; 8 | public ISyntaxElement Left { get; } 9 | public string Op { get; } 10 | public ISyntaxElement Right { get; } 11 | 12 | public BitwiseNode(ISyntaxElement left, string op, ISyntaxElement right, TokenPosition position) 13 | : base(position) 14 | { 15 | Left = left; 16 | Op = op; 17 | Right = right; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/LogicalNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class LogicalNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Logical; 8 | public ISyntaxElement Left { get; } 9 | public string Op { get; } 10 | public ISyntaxElement Right { get; } 11 | 12 | public LogicalNode(ISyntaxElement left, string op, ISyntaxElement right, TokenPosition position) 13 | : base(position) 14 | { 15 | Left = left; 16 | Op = op; 17 | Right = right; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/AdditiveNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class AdditiveNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Additive; 8 | public ISyntaxElement Left { get; } 9 | public string Op { get; } 10 | public ISyntaxElement Right { get; } 11 | 12 | public AdditiveNode(ISyntaxElement left, string op, ISyntaxElement right, TokenPosition position) 13 | : base(position) 14 | { 15 | Left = left; 16 | Op = op; 17 | Right = right; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/EqualityNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class EqualityNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Equality; 8 | public ISyntaxElement Left { get; } 9 | public string Op { get; } 10 | public ISyntaxElement Right { get; } 11 | 12 | public EqualityNode(ISyntaxElement left, string op, ISyntaxElement right, TokenPosition position) 13 | : base(position) 14 | { 15 | Left = left; 16 | Op = op; 17 | Right = right; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/RelationalNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class RelationalNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Relational; 8 | public ISyntaxElement Left { get; } 9 | public string Op { get; } 10 | public ISyntaxElement Right { get; } 11 | 12 | public RelationalNode(ISyntaxElement left, string op, ISyntaxElement right, TokenPosition position) 13 | : base(position) 14 | { 15 | Left = left; 16 | Op = op; 17 | Right = right; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/SyntaxNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public abstract class SyntaxNode : ISyntaxNode 10 | { 11 | public ISyntaxNode Parent { get; set; } 12 | public TokenPosition Position { get; } 13 | public bool IsToken => false; 14 | public abstract SyntaxType Type { get; } 15 | 16 | public SyntaxNode(TokenPosition position) 17 | { 18 | Position = position; 19 | } 20 | 21 | public abstract void Accept(ISyntaxElementVisitor visitor); 22 | 23 | public override string ToString() 24 | { 25 | return Type.ToString(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /TaffyScript/TaffyScriptLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Reflection; 7 | 8 | namespace TaffyScript 9 | { 10 | public static class TaffyScriptLoader 11 | { 12 | /// 13 | /// Loads a TaffyScript from the specified path and initializes it. 14 | /// 15 | /// 16 | public static void Load(string path) 17 | { 18 | var asm = Assembly.LoadFile(path); 19 | var name = asm.GetName().Name; 20 | var init = asm.GetType($"{name}.{name}_Initializer"); 21 | init.GetMethod("Initialize", BindingFlags.Public | BindingFlags.Static).Invoke(null, null); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/MultiplicativeNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class MultiplicativeNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Multiplicative; 8 | public ISyntaxElement Left { get; } 9 | public string Op { get; } 10 | public ISyntaxElement Right { get; } 11 | 12 | public MultiplicativeNode(ISyntaxElement left, string op, ISyntaxElement right, TokenPosition position) 13 | : base(position) 14 | { 15 | Left = left; 16 | Op = op; 17 | Right = right; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ObjectNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class ObjectNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Object; 8 | public string Name { get; } 9 | public ISyntaxElement Inherits { get; } 10 | public List Scripts { get; } 11 | 12 | public ObjectNode(string name, ISyntaxElement inherits, List scripts, TokenPosition position) 13 | : base(position) 14 | { 15 | Name = name; 16 | Inherits = inherits; 17 | Scripts = scripts; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ScriptNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class ScriptNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Script; 8 | public string Name { get; } 9 | public List Arguments { get; } 10 | public ISyntaxElement Body { get; } 11 | 12 | public ScriptNode(string name, List arguments, ISyntaxElement body, TokenPosition position) 13 | : base(position) 14 | { 15 | Name = name; 16 | Arguments = arguments; 17 | Body = body; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ConstantToken.cs: -------------------------------------------------------------------------------- 1 | namespace TaffyScript.Compiler.Syntax 2 | { 3 | public class ConstantToken : SyntaxToken, IConstantToken 4 | { 5 | public override SyntaxType Type => SyntaxType.Constant; 6 | 7 | public override string Name { get; } 8 | public T Value { get; } 9 | public ConstantType ConstantType { get; } 10 | public object WeakValue => Value; 11 | 12 | 13 | public ConstantToken(string name, T realValue, ConstantType type, TokenPosition position) 14 | : base(position) 15 | { 16 | Name = name; 17 | ConstantType = type; 18 | Value = realValue; 19 | } 20 | 21 | public override void Accept(ISyntaxElementVisitor visitor) 22 | { 23 | visitor.Visit(this); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ConditionalNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class ConditionalNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Conditional; 8 | public ISyntaxElement Condition { get; } 9 | public ISyntaxElement Left { get; } 10 | public ISyntaxElement Right { get; } 11 | 12 | public ConditionalNode(ISyntaxElement condition, ISyntaxElement left, ISyntaxElement right, TokenPosition position) 13 | : base(position) 14 | { 15 | Condition = condition; 16 | Left = left; 17 | Right = right; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/IfNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class IfNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.If; 8 | public ISyntaxElement Condition { get; } 9 | public ISyntaxElement ThenBrach { get; } 10 | public ISyntaxElement ElseBranch { get; } 11 | 12 | public IfNode(ISyntaxElement condition, ISyntaxElement thenBrach, ISyntaxElement elseBranch, TokenPosition position) 13 | : base(position) 14 | { 15 | Condition = condition; 16 | ThenBrach = thenBrach; 17 | ElseBranch = elseBranch; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Symbols/ImportObjectLeaf.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using TaffyScript.Compiler.Syntax; 7 | 8 | namespace TaffyScript.Compiler 9 | { 10 | public class ImportObjectLeaf : SymbolLeaf 11 | { 12 | public ImportObjectNode ImportObject { get; } 13 | public System.Reflection.ConstructorInfo Constructor { get; set; } 14 | public System.Reflection.MethodInfo TryGetDelegate { get; set; } 15 | public bool HasImportedObject { get; set; } = false; 16 | 17 | 18 | public ImportObjectLeaf(SymbolNode parent, string name, ImportObjectNode importObject) 19 | : base(parent, name, SymbolType.Object, SymbolScope.Global) 20 | { 21 | ImportObject = importObject; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/BaseNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public class BaseNode : SyntaxNode 10 | { 11 | public override SyntaxType Type => SyntaxType.Base; 12 | public List Arguments { get; } 13 | public TokenPosition EndPosition { get; } 14 | 15 | public BaseNode(List arguments, TokenPosition endPosition, TokenPosition position) 16 | : base(position) 17 | { 18 | Arguments = arguments; 19 | EndPosition = endPosition; 20 | } 21 | 22 | public override void Accept(ISyntaxElementVisitor visitor) 23 | { 24 | visitor.Visit(this); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/SyntaxToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public abstract class SyntaxToken : ISyntaxToken 10 | { 11 | public ISyntaxNode Parent { get; set; } 12 | public abstract SyntaxType Type { get; } 13 | public abstract string Name { get; } 14 | public TokenPosition Position { get; } 15 | public bool IsToken => true; 16 | 17 | public SyntaxToken(TokenPosition position) 18 | { 19 | Position = position; 20 | } 21 | 22 | public abstract void Accept(ISyntaxElementVisitor visitor); 23 | 24 | public override string ToString() 25 | { 26 | return Type.ToString(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/LambdaNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace TaffyScript.Compiler.Syntax 6 | { 7 | public class LambdaNode : SyntaxNode 8 | { 9 | public override SyntaxType Type => SyntaxType.Lambda; 10 | public string Scope { get; } 11 | public List Arguments { get; } 12 | public BlockNode Body { get; } 13 | 14 | public LambdaNode(string scope, List arguments, BlockNode body, TokenPosition position) 15 | : base(position) 16 | { 17 | Scope = scope; 18 | Arguments = arguments; 19 | Body = body; 20 | } 21 | 22 | public override void Accept(ISyntaxElementVisitor visitor) 23 | { 24 | visitor.Visit(this); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/NewNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class NewNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.New; 8 | public ISyntaxElement TypeName { get; } 9 | public List Arguments { get; } 10 | public TokenPosition EndPosition { get; } 11 | 12 | public NewNode(ISyntaxElement typeName, List arguments, TokenPosition endPosition, TokenPosition position) 13 | : base(position) 14 | { 15 | TypeName = typeName; 16 | Arguments = arguments; 17 | EndPosition = endPosition; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Samples/Moddable/GameBase/player.tfs: -------------------------------------------------------------------------------- 1 | using Microsoft.Xna.Framework.Input 2 | 3 | namespace GameBase { 4 | 5 | import Input.KeyCheck(int) as key_check; 6 | 7 | object par_character_select { 8 | event create { 9 | name = ""; 10 | player = noone; 11 | } 12 | } 13 | 14 | object obj_default_select : par_character_select { 15 | event create { 16 | name = "Default" 17 | player = obj_player; 18 | } 19 | } 20 | 21 | object obj_player { 22 | event create { 23 | speed = 3; 24 | x = 0; 25 | y = 0; 26 | } 27 | 28 | event step { 29 | var hspd = key_check(Keys.Right) - key_check(Keys.Left); 30 | var vspd = key_check(Keys.Down) - key_check(Keys.Up); 31 | x += hspd * speed; 32 | y += vspd * speed; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/script_composition.tfs: -------------------------------------------------------------------------------- 1 | //This file makes sure weird scripts and object inheritance compiles properly. 2 | 3 | using UnitTest; 4 | 5 | namespace LanguageTests { 6 | 7 | script scr_comp_tests() { 8 | test_it("Script Composition"); 9 | var obj = new obj_comp3(); 10 | assert_equal(obj.moo(), "moomoo"); 11 | } 12 | 13 | script scr_comp1() { 14 | 15 | } 16 | 17 | script scr_comp2 { 18 | 19 | } 20 | 21 | object obj_comp1 { 22 | 23 | } 24 | 25 | object obj_comp2 : obj_comp1 { 26 | script ev_comp1() { 27 | 28 | } 29 | 30 | script ev_comp2 { 31 | 32 | } 33 | 34 | script moo() { 35 | return "moo"; 36 | } 37 | } 38 | 39 | object obj_comp3 : obj_comp2 { 40 | script moo() { 41 | return "moo" + event_inherited(); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/FunctionCallNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class FunctionCallNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.FunctionCall; 8 | public ISyntaxElement Callee { get; } 9 | public List Arguments { get; } 10 | public TokenPosition EndPosition { get; } 11 | 12 | public FunctionCallNode(ISyntaxElement callee, List arguments, TokenPosition endPosition, TokenPosition position) 13 | : base(position) 14 | { 15 | Callee = callee; 16 | Arguments = arguments; 17 | EndPosition = endPosition; 18 | } 19 | 20 | public override void Accept(ISyntaxElementVisitor visitor) 21 | { 22 | visitor.Visit(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/PlayState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Microsoft.Xna.Framework; 7 | using Microsoft.Xna.Framework.Content; 8 | using Microsoft.Xna.Framework.Graphics; 9 | using TaffyScript; 10 | 11 | namespace Moddable 12 | { 13 | public class PlayState : IGameState 14 | { 15 | private Player _player; 16 | 17 | public PlayState(string playerType, ContentManager content) 18 | { 19 | var texture = content.Load("Owl_Small"); 20 | _player = new Player(playerType, texture); 21 | } 22 | 23 | public void Update(GameTime gameTime) 24 | { 25 | _player.Step(); 26 | } 27 | 28 | public void Draw(SpriteBatch batch) 29 | { 30 | _player.Draw(batch); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ImportObject/ImportObjectMethod.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public class ImportObjectMethod 10 | { 11 | public string ExternalName { get; } 12 | public string ImportName { get; } 13 | public List Generics { get; } 14 | public List Arguments { get; } 15 | public TokenPosition Position { get; } 16 | 17 | public ImportObjectMethod(string externalName, string importName, List generics, List arguments, TokenPosition position) 18 | { 19 | ExternalName = externalName; 20 | ImportName = importName; 21 | Generics = generics; 22 | Arguments = arguments; 23 | Position = position; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ForNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class ForNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.For; 8 | public ISyntaxElement Initialize { get; } 9 | public ISyntaxElement Condition { get; } 10 | public ISyntaxElement Increment { get; } 11 | public ISyntaxElement Body { get; } 12 | 13 | public ForNode(ISyntaxElement initialize, ISyntaxElement condition, ISyntaxElement increment, ISyntaxElement body, TokenPosition position) 14 | : base(position) 15 | { 16 | Initialize = initialize; 17 | Condition = condition; 18 | Increment = increment; 19 | Body = body; 20 | } 21 | 22 | public override void Accept(ISyntaxElementVisitor visitor) 23 | { 24 | visitor.Visit(this); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/SwitchNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class SwitchNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.Switch; 8 | public ISyntaxElement Value { get; } 9 | public List Cases { get; } 10 | public ISyntaxElement DefaultCase { get; } 11 | public int DefaultIndex { get; } 12 | 13 | public SwitchNode(ISyntaxElement value, List cases, ISyntaxElement defaultCase, int defaultIndex, TokenPosition position) 14 | : base(position) 15 | { 16 | Value = value; 17 | Cases = cases; 18 | DefaultCase = defaultCase; 19 | DefaultIndex = defaultIndex; 20 | } 21 | 22 | public override void Accept(ISyntaxElementVisitor visitor) 23 | { 24 | visitor.Visit(this); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/Concrete/ImportScriptNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler.Syntax 4 | { 5 | public class ImportScriptNode : SyntaxNode 6 | { 7 | public override SyntaxType Type => SyntaxType.ImportScript; 8 | public string DotNetType { get; } 9 | public string MethodName { get; } 10 | public string ImportName { get; } 11 | public List Arguments { get; } 12 | 13 | public ImportScriptNode(string dotNetType, string methodName, string internalName, List arguments, TokenPosition position) 14 | : base(position) 15 | { 16 | DotNetType = dotNetType; 17 | MethodName = methodName; 18 | ImportName = internalName; 19 | Arguments = arguments; 20 | } 21 | 22 | public override void Accept(ISyntaxElementVisitor visitor) 23 | { 24 | visitor.Visit(this); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /TaffyScript/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript 8 | { 9 | public static class Extensions 10 | { 11 | public static void Shuffle(Array array) 12 | { 13 | int n = array.Length; 14 | while(n > 1) 15 | { 16 | var k = Bcl.Rng.Next(n--); 17 | var value = array.GetValue(k); 18 | array.SetValue(array.GetValue(n), k); 19 | array.SetValue(value, n); 20 | } 21 | } 22 | 23 | public static void Shuffle(this IList list) 24 | { 25 | int n = list.Count; 26 | while(n > 1) 27 | { 28 | var k = Bcl.Rng.Next(n--); 29 | var value = list[k]; 30 | list[k] = list[n]; 31 | list[n] = value; 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/return.tfs: -------------------------------------------------------------------------------- 1 | using UnitTest; 2 | 3 | namespace LanguageTests { 4 | script run_return_tests() { 5 | var tests = new obj_unit_test("Return Tests", 6 | return_something_works, 7 | return_nothing_works); 8 | tests.run_tests(); 9 | } 10 | 11 | script return_something_works() { 12 | test_it("script { return val }"); 13 | var result = return_something(); 14 | assert_equal(result, 2); 15 | } 16 | 17 | script return_nothing_works() { 18 | test_it("script { return }"); 19 | var result = return_nothing_semicolon(); 20 | assert(is_null(result)); 21 | result = return_nothing_end_brace(); 22 | assert(is_null(result)); 23 | } 24 | 25 | script return_something() { 26 | return 2; 27 | } 28 | 29 | script return_nothing_semicolon() { 30 | return; 31 | } 32 | 33 | script return_nothing_end_brace() { 34 | return 35 | } 36 | } -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/Content/Content.mgcb: -------------------------------------------------------------------------------- 1 | 2 | #----------------------------- Global Properties ----------------------------# 3 | 4 | /outputDir:bin/$(Platform) 5 | /intermediateDir:obj/$(Platform) 6 | /platform:Windows 7 | /config: 8 | /profile:Reach 9 | /compress:False 10 | 11 | #-------------------------------- References --------------------------------# 12 | 13 | 14 | #---------------------------------- Content ---------------------------------# 15 | 16 | #begin font.spritefont 17 | /importer:FontDescriptionImporter 18 | /processor:FontDescriptionProcessor 19 | /processorParam:PremultiplyAlpha=True 20 | /processorParam:TextureFormat=Compressed 21 | /build:font.spritefont 22 | 23 | #begin Owl_Small.png 24 | /importer:TextureImporter 25 | /processor:TextureProcessor 26 | /processorParam:ColorKeyColor=255,0,255,255 27 | /processorParam:ColorKeyEnabled=True 28 | /processorParam:GenerateMipmaps=False 29 | /processorParam:PremultiplyAlpha=True 30 | /processorParam:ResizeToPowerOfTwo=False 31 | /processorParam:MakeSquare=False 32 | /processorParam:TextureFormat=Color 33 | /build:Owl_Small.png 34 | 35 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Front End/LexicalAnalysis/Token.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.FrontEnd 8 | { 9 | public class Token 10 | { 11 | /// 12 | /// The location within the stream that this token was found. 13 | /// 14 | public TokenPosition Position { get; } 15 | 16 | /// 17 | /// The type of this token. 18 | /// 19 | public TokenType Type { get; } 20 | 21 | /// 22 | /// The value of this token. 23 | /// 24 | public string Text { get; } 25 | 26 | public Token(TokenType type, string text, TokenPosition position) 27 | { 28 | Type = type; 29 | Text = text; 30 | Position = position; 31 | } 32 | 33 | public override string ToString() 34 | { 35 | return $"Token: Type {Type} | Text {Text} | Position {Position}"; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Samples/HelloLanguage/source.tfs: -------------------------------------------------------------------------------- 1 | using HelloLanguage; 2 | 3 | script main { 4 | namespace_script(); 5 | HelloLanguage.Utils.Console.trace("HelloLanguage"); 6 | var inst = instance_create(namespace_object); 7 | //Different from trace defined in this file. 8 | trace(inst.i); 9 | } 10 | 11 | namespace HelloLanguage { 12 | script namespace_script { 13 | show_debug_message("script from ns"); 14 | } 15 | 16 | script test { 17 | show_debug_message(argument0); 18 | } 19 | 20 | object namespace_object { 21 | event create { 22 | i = 0; 23 | } 24 | } 25 | 26 | enum Color { 27 | Red, 28 | Green, 29 | Blue 30 | } 31 | } 32 | 33 | namespace HelloLanguage.Utils.Console { 34 | script trace { 35 | if(argument_count == 0) { 36 | show_debug_message(""); 37 | exit; 38 | } 39 | var output = string(argument0); 40 | for(var i = 1; i < argument_count; i++) { 41 | output += ", " + string(argument[i]); 42 | } 43 | show_debug_message(output); 44 | } 45 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Precisamento LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/tests.tfs: -------------------------------------------------------------------------------- 1 | using UnitTest; 2 | 3 | namespace LanguageTests { 4 | script main { 5 | run_addition_tests(); 6 | print(""); 7 | run_subtraction_tests(); 8 | print(""); 9 | run_multiplication_tests(); 10 | print(""); 11 | run_division_tests(); 12 | print(""); 13 | run_modulus_tests(); 14 | print(""); 15 | run_postfix_tests(); 16 | print(""); 17 | run_prefix_tests(); 18 | print(""); 19 | run_ternary_tests(); 20 | print(""); 21 | run_import_tests(); 22 | print(""); 23 | run_array_tests(); 24 | print(""); 25 | run_list_tests(); 26 | print(""); 27 | run_map_tests(); 28 | print(""); 29 | run_with_tests(); 30 | print(""); 31 | run_lambda_tests(); 32 | print(""); 33 | run_return_tests(); 34 | print(""); 35 | run_math_tests(); 36 | print(""); 37 | run_string_tests(); 38 | print(""); 39 | run_reflection_tests(); 40 | print(""); 41 | run_repeat_tests(); 42 | print(""); 43 | } 44 | } -------------------------------------------------------------------------------- /Samples/Threading/TaffyScript.Threading/Locks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | 7 | namespace TaffyScript.Threading 8 | { 9 | [WeakBaseType] 10 | public static class Locks 11 | { 12 | [WeakMethod] 13 | public static TsObject moniter_enter(ITsInstance inst, TsObject[] args) 14 | { 15 | Monitor.Enter(args[0].GetValue()); 16 | return TsObject.Empty(); 17 | } 18 | 19 | [WeakMethod] 20 | public static TsObject moniter_try_enter(ITsInstance inst, TsObject[] args) 21 | { 22 | if (args.Length < 1) 23 | throw new ArgumentOutOfRangeException("args", "There must be at least one argument to call moniter_try_enter"); 24 | if (args.Length == 2) 25 | return Monitor.TryEnter(args[0].GetValue(), (int)args[1]); 26 | else 27 | return Monitor.TryEnter(args[0].GetValue()); 28 | } 29 | 30 | [WeakMethod] 31 | public static TsObject moniter_exit(ITsInstance inst, TsObject[] args) 32 | { 33 | Monitor.Exit(args[0].GetValue()); 34 | return TsObject.Empty(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/SyntaxType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler 8 | { 9 | public enum SyntaxType 10 | { 11 | //Node 12 | Root, 13 | Assign, 14 | Locals, 15 | Conditional, 16 | Logical, 17 | Bitwise, 18 | Equality, 19 | Relational, 20 | Shift, 21 | Additive, 22 | Multiplicative, 23 | Prefix, 24 | FunctionCall, 25 | MemberAccess, 26 | ArrayAccess, 27 | Postfix, 28 | ArrayLiteral, 29 | Declare, 30 | If, 31 | Switch, 32 | Case, 33 | Default, 34 | While, 35 | Repeat, 36 | With, 37 | Do, 38 | For, 39 | Return, 40 | Block, 41 | ImportScript, 42 | Enum, 43 | Script, 44 | ArgumentAccess, 45 | Object, 46 | Usings, 47 | Namespace, 48 | New, 49 | ImportObject, 50 | Lambda, 51 | Base, 52 | 53 | //Token 54 | Constant, 55 | Variable, 56 | End, 57 | Break, 58 | Continue, 59 | ReadOnly 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/object_import.tfs: -------------------------------------------------------------------------------- 1 | using UnitTest; 2 | using TaffyScript.Collections; 3 | 4 | namespace LanguageTests { 5 | 6 | script run_import_tests() { 7 | var tests = new obj_unit_test("Import Tests", import_create_ds_list); 8 | tests.run_tests(); 9 | } 10 | 11 | script import_create_ds_list() { 12 | test_it("import new List"); 13 | var list = new List(); 14 | list.add("Hello"); 15 | var value = list.get(0); 16 | assert_equal(value, "Hello"); 17 | } 18 | 19 | //Explicitly import class and method. 20 | //Please note that this is an example created for the tests 21 | //The BCL already has a List import that should be used instead. 22 | import object List as obj_list { 23 | //Import fields and properties. 24 | Count as size; 25 | 26 | //Import single constructor. Doesn't have to be parameterless ctor. 27 | new(); 28 | 29 | //Import methods with a new name. 30 | Add(object) as add; 31 | Clear() as clear; 32 | RemoveAt(int) as delete; 33 | get_Item(int) as get; 34 | set_Item(int, object) as set; 35 | Insert(int, object) as insert; 36 | } 37 | 38 | //Auto generate wrapper class. 39 | import object(typing=strong, casing=snake_case) HashSet as ds_set; 40 | } -------------------------------------------------------------------------------- /Samples/Moddable/ModdableExtern/Input.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Microsoft.Xna.Framework.Input; 7 | 8 | namespace ModdableExtern 9 | { 10 | public static class Input 11 | { 12 | private static KeyboardState _keyboardCurrent; 13 | private static KeyboardState _keyboardPrevious; 14 | 15 | public static bool KeyCheck(int key) 16 | { 17 | if (!Enum.IsDefined(typeof(Keys), key)) 18 | throw new ArgumentException("The given key was not valid", "key"); 19 | return KeyCheck((Keys)key); 20 | } 21 | 22 | public static bool KeyCheck(Keys key) 23 | { 24 | return _keyboardCurrent.IsKeyDown(key); 25 | } 26 | 27 | public static bool KeyCheckPressed(int key) 28 | { 29 | if (!Enum.IsDefined(typeof(Keys), key)) 30 | throw new ArgumentException("The given key was not valid", "key"); 31 | return KeyCheckPressed((Keys)key); 32 | } 33 | 34 | public static bool KeyCheckPressed(Keys key) 35 | { 36 | return _keyboardCurrent.IsKeyDown(key) && !_keyboardPrevious.IsKeyDown(key); 37 | } 38 | 39 | public static void Update() 40 | { 41 | _keyboardPrevious = _keyboardCurrent; 42 | _keyboardCurrent = Keyboard.GetState(); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Moddable")] 9 | [assembly: AssemblyProduct("Moddable")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8314c789-de45-41ca-9cb5-9a54485377c7")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /TaffyScript/Collections/EventCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace TaffyScript.Collections 5 | { 6 | /// 7 | /// Provides an interface for mapping s to s or other delegates for addition and removal. 8 | /// 9 | /// 10 | public class EventCache 11 | { 12 | private Dictionary>> _cache = new Dictionary>>(); 13 | 14 | public void Cache(T key, TsDelegate del, Delegate handler) 15 | { 16 | if (!_cache.TryGetValue(key, out var list)) 17 | { 18 | list = new List>(); 19 | _cache.Add(key, list); 20 | } 21 | list.Add(new KeyValuePair(del, handler)); 22 | } 23 | 24 | public bool TryRemove(T key, TsDelegate del, out Delegate handler) 25 | { 26 | if (!_cache.TryGetValue(key, out var list)) 27 | { 28 | handler = null; 29 | return false; 30 | } 31 | 32 | foreach (var item in list) 33 | { 34 | if (item.Key == del) 35 | { 36 | handler = item.Value; 37 | return true; 38 | } 39 | } 40 | 41 | handler = null; 42 | return false; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Samples/Moddable/ModdableExtern/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ModdableExtern")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ModdableExtern")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("a4b77ad8-18d2-41c4-8b0f-fdf39e2ebc32")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Samples/TestSuite/TaffyScript.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TaffyScript.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TaffyScript.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0c33b274-4c13-4f74-9a4c-83c3adb82408")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /TaffyScript.CommandLine/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TaffyScript.CommandLine")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TaffyScript.CommandLine")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("ff4bc25b-646a-4849-bfc1-4731cec9d456")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Backend/BuildConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Xml.Serialization; 8 | 9 | namespace TaffyScript.Compiler.Backend 10 | { 11 | [XmlRoot(ElementName = "Build")] 12 | public class BuildConfig 13 | { 14 | public string Output { get; set; } = "bin/Output"; 15 | 16 | [XmlArray] 17 | [XmlArrayItem(ElementName = "Reference")] 18 | public List References { get; set; } = new List(); 19 | 20 | [XmlArray] 21 | [XmlArrayItem(ElementName = "Exclude")] 22 | public List Excludes { get; set; } = new List(); 23 | 24 | public string EntryPoint { get; set; } = "main"; 25 | public string Product { get; set; } = ""; 26 | public string Version { get; set; } = "0.0.0"; 27 | public string Company { get; set; } = ""; 28 | public string Copyright { get; set; } = ""; 29 | public string Trademark { get; set; } = ""; 30 | public string Description { get; set; } = ""; 31 | 32 | public CompileMode Mode { get; set; } = CompileMode.Debug; 33 | 34 | public void Save(string path) 35 | { 36 | path = Path.Combine(path, "build.cfg"); 37 | using(var sw = new StreamWriter(path)) 38 | { 39 | var serializer = new XmlSerializer(typeof(BuildConfig)); 40 | serializer.Serialize(sw, this); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Backend/Compiler/TypeEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Reflection.Emit; 7 | 8 | namespace TaffyScript.Compiler.Backend 9 | { 10 | // These specialized classes generate a hash code based off of a 11 | // Types name. These are necessary because a TypeBuilders 12 | // hashcode changes when CreateType is called. In order to 13 | // lookup the type in a dictionary, this custom implementation 14 | // is needed. 15 | 16 | public class TypeEqualityComparer : IEqualityComparer 17 | { 18 | private static TypeEqualityComparer _single = new TypeEqualityComparer(); 19 | 20 | public static TypeEqualityComparer Single => _single; 21 | 22 | public bool Equals(Type x, Type y) 23 | { 24 | return x == y; 25 | } 26 | 27 | public int GetHashCode(Type obj) 28 | { 29 | return obj.FullName.GetHashCode(); 30 | } 31 | } 32 | 33 | public class TypeBuilderEqualityComparer : IEqualityComparer 34 | { 35 | private static TypeBuilderEqualityComparer _single = new TypeBuilderEqualityComparer(); 36 | 37 | public static TypeBuilderEqualityComparer Single => _single; 38 | 39 | public bool Equals(TypeBuilder x, TypeBuilder y) 40 | { 41 | return x == y; 42 | } 43 | 44 | public int GetHashCode(TypeBuilder obj) 45 | { 46 | return obj.FullName.GetHashCode(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /TaffyScript/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TaffyScript")] 9 | [assembly: AssemblyDescription("The basic implementation of data types in the TaffyScript language.")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Precisamento")] 12 | [assembly: AssemblyProduct("TaffyScript")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("68399d06-20df-4ce8-9920-bd82df2b8f69")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.9.3")] 36 | [assembly: AssemblyFileVersion("1.9.3")] -------------------------------------------------------------------------------- /TaffyScript.Compiler/Symbols/SymbolNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TaffyScript.Compiler 4 | { 5 | public class SymbolNode : ISymbol 6 | { 7 | public SymbolType Type { get; } 8 | public SymbolScope Scope { get; } 9 | public string Name { get; } 10 | public Dictionary Children { get; } = new Dictionary(); 11 | public bool IsLeaf => false; 12 | public SymbolNode Parent { get; } 13 | public List Pending { get; } = new List(); 14 | 15 | public SymbolNode(SymbolNode parent, string name, SymbolType type) 16 | : this(parent, name, type, SymbolScope.Global) 17 | { 18 | } 19 | 20 | public SymbolNode(SymbolNode parent, string name, SymbolType type, SymbolScope scope) 21 | { 22 | Parent = parent; 23 | Name = name; 24 | Type = type; 25 | Scope = scope; 26 | } 27 | 28 | public SymbolNode EnterNew(string name, SymbolType type) => EnterNew(name, type, SymbolScope.Global); 29 | 30 | public SymbolNode EnterNew(string name, SymbolType type, SymbolScope scope) 31 | { 32 | var child = new SymbolNode(this, name, type, scope); 33 | Children.Add(name, child); 34 | return child; 35 | } 36 | 37 | public void AddPending(string name) 38 | { 39 | Pending.Add(name); 40 | } 41 | 42 | public override string ToString() 43 | { 44 | return $"SymbolNode {Type} {Name}"; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /TaffyScript.Compiler/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TaffyScript.Compiler")] 9 | [assembly: AssemblyDescription("The source for the TaffyScript language compiler")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Precisamento")] 12 | [assembly: AssemblyProduct("TaffyScript.Compiler")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("4022f406-fce6-4a8d-b99f-6ef6c406248a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.0.0")] 36 | [assembly: AssemblyFileVersion("1.1.0.0")] 37 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Backend/CompilerResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Reflection; 7 | 8 | namespace TaffyScript.Compiler.Backend 9 | { 10 | public class CompilerResult 11 | { 12 | /// 13 | /// If the compile was successful, contains the output assembly. 14 | /// 15 | public Assembly CompiledAssebmly { get; } 16 | 17 | /// 18 | /// If the compile failed, contains a list of the encountered errors. 19 | /// 20 | public List Errors { get; } 21 | 22 | /// 23 | /// Warnings that aren't breaking, but are generally considered bad practice. 24 | /// 25 | public List Warnings { get; } 26 | 27 | /// 28 | /// If the compile was successful, contains the path to the output assembly. 29 | /// 30 | public string PathToAssembly { get; } 31 | 32 | public CompilerResult(Assembly asm, string path, IErrorLogger errorLogger) 33 | { 34 | CompiledAssebmly = asm; 35 | PathToAssembly = path; 36 | Errors = errorLogger.Errors; 37 | Warnings = errorLogger.Warnings; 38 | } 39 | 40 | public CompilerResult(IErrorLogger errorLogger) 41 | { 42 | CompiledAssebmly = null; 43 | PathToAssembly = null; 44 | Errors = errorLogger.Errors; 45 | Warnings = errorLogger.Warnings; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Samples/Threading/TaffyScript.Threading/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using TaffyScript; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("TaffyScript.Threading")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("TaffyScript.Threading")] 14 | [assembly: AssemblyCopyright("Copyright © 2018")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("3d25de02-f1a9-47e0-b570-1dcf3882d7d4")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("1.0.0.0")] 37 | [assembly: AssemblyFileVersion("1.0.0.0")] 38 | [assembly: WeakLibrary] 39 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/StringUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler 8 | { 9 | public static class StringUtils 10 | { 11 | public static string ConvertToCamelCase(string value) 12 | { 13 | var sb = new StringBuilder(); 14 | var split = value.Split(new[] { '_' }, StringSplitOptions.RemoveEmptyEntries); 15 | for(var i = 0; i < split.Length; i++) 16 | { 17 | if (i == 0) 18 | sb.Append(char.ToLower(split[0][0])); 19 | else 20 | sb.Append(char.ToUpper(split[i][0])); 21 | 22 | sb.Append(split[i].Substring(1, split[i].Length - 1)); 23 | } 24 | return sb.ToString(); 25 | } 26 | 27 | public static string ConvertToPascalCase(string value) 28 | { 29 | var sb = new StringBuilder(); 30 | var split = value.Split(new[] { '_' }, StringSplitOptions.RemoveEmptyEntries); 31 | for (var i = 0; i < split.Length; i++) 32 | { 33 | sb.Append(char.ToUpper(split[i][0])); 34 | sb.Append(split[i].Substring(1, split[i].Length - 1)); 35 | } 36 | return sb.ToString(); 37 | } 38 | 39 | public static string ConvertToSnakeCase(string value) 40 | { 41 | return string.Concat(value.Select((x, i) => i == 0 ? char.ToLower(x).ToString() : char.IsUpper(x) ? "_" + char.ToLower(x) : x.ToString())); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | true/pm 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Front End/LexicalAnalysis/TokenPosition.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler 8 | { 9 | /// 10 | /// Represents a position within a document/stream where a was found. 11 | /// 12 | public class TokenPosition 13 | { 14 | /// 15 | /// The position on the line where the was found. 16 | /// 17 | public int Column { get; } 18 | 19 | /// 20 | /// The index in the document/stream where the was found. 21 | /// 22 | public int Index { get; } 23 | 24 | /// 25 | /// The line number where the was found. 26 | /// 27 | public int Line { get; } 28 | 29 | public string File { get; } 30 | 31 | public TokenPosition(int index, int line, int column, string file) 32 | { 33 | Index = index; 34 | Line = line; 35 | Column = column; 36 | File = file; 37 | } 38 | 39 | public override string ToString() 40 | { 41 | var sb = new StringBuilder(); 42 | if (File != null) 43 | { 44 | sb.Append("in file "); 45 | sb.Append(File); 46 | sb.Append(" "); 47 | } 48 | sb.Append("at line "); 49 | sb.Append(Line); 50 | sb.Append(", column "); 51 | sb.Append(Column); 52 | return sb.ToString(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/Player.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Microsoft.Xna.Framework; 7 | using Microsoft.Xna.Framework.Graphics; 8 | using TaffyScript; 9 | 10 | namespace Moddable 11 | { 12 | /// 13 | /// Wraps a player TsObject 14 | /// 15 | public class Player 16 | { 17 | private const string Parent = "GameBase.obj_player"; 18 | private const string StepEvent = "step"; 19 | 20 | private TsInstance _source; 21 | private TsDelegate _step = null; 22 | private Texture2D _texture; 23 | 24 | public float X 25 | { 26 | get => (float)_source["x"]; 27 | set => _source["x"] = value; 28 | } 29 | 30 | public float Y 31 | { 32 | get => (float)_source["y"]; 33 | set => _source["y"] = value; 34 | } 35 | 36 | public Player(string playerType, Texture2D texture) 37 | { 38 | if (playerType == Parent || TsInstance.ObjectIsAncestor(playerType, Parent)) 39 | { 40 | _source = new TsInstance(playerType); 41 | _step = _source.GetDelegate(StepEvent); 42 | _texture = texture; 43 | } 44 | else 45 | throw new InvalidOperationException("Received an invalid player type."); 46 | } 47 | 48 | public void Step() 49 | { 50 | _step?.Invoke(_source); 51 | } 52 | 53 | public void Draw(SpriteBatch batch) 54 | { 55 | batch.Draw(_texture, new Vector2(X, Y), Color.White); 56 | } 57 | 58 | public void Destroy() 59 | { 60 | _source.Destroy(); 61 | _source = null; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/Front End/LexicalAnalysis/TokenType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.FrontEnd 8 | { 9 | public enum TokenType 10 | { 11 | AndEquals, 12 | Argument, 13 | As, 14 | Assign, 15 | Base, 16 | BitwiseAnd, 17 | BitwiseOr, 18 | Bool, 19 | Break, 20 | Case, 21 | CloseBrace, 22 | CloseBracket, 23 | CloseParen, 24 | Colon, 25 | Comma, 26 | Complement, 27 | Continue, 28 | Decrement, 29 | Default, 30 | DivEquals, 31 | Divide, 32 | Do, 33 | Dot, 34 | Else, 35 | Enum, 36 | EoF, 37 | Equal, 38 | Event, 39 | For, 40 | GreaterThan, 41 | GreaterThanOrEqual, 42 | Identifier, 43 | If, 44 | Import, 45 | Increment, 46 | LessThan, 47 | LessThanOrEqual, 48 | LogicalAnd, 49 | LogicalOr, 50 | Minus, 51 | ModEquals, 52 | Modulo, 53 | MulEquals, 54 | Multiply, 55 | Namespace, 56 | New, 57 | Not, 58 | NotEqual, 59 | Number, 60 | Object, 61 | OpenBrace, 62 | OpenBracket, 63 | OpenParen, 64 | OrEquals, 65 | Plus, 66 | PlusEquals, 67 | QuestionMark, 68 | ReadOnly, 69 | Repeat, 70 | Return, 71 | Script, 72 | SemiColon, 73 | ShiftLeft, 74 | ShiftRight, 75 | String, 76 | SubEquals, 77 | Switch, 78 | Until, 79 | Using, 80 | Var, 81 | While, 82 | With, 83 | Xor, 84 | XorEquals 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/repeat.tfs: -------------------------------------------------------------------------------- 1 | using UnitTest; 2 | 3 | namespace LanguageTests { 4 | script run_repeat_tests() { 5 | var tests = new obj_unit_test("Repeat Tests", 6 | run_repeat_faulty_tests, 7 | repeat_number_literal, 8 | repeat_number_variable, 9 | repeat_break, 10 | repeat_continue); 11 | tests.run_tests(); 12 | } 13 | 14 | script run_repeat_faulty_tests() { 15 | assert(try_expect(repeat_string_variable, "InvalidTsTypeException")); 16 | test_it("Faulty Repeat"); 17 | } 18 | 19 | script repeat_number_literal() { 20 | test_it("repeat(num)"); 21 | var i = 0; 22 | repeat(5) { 23 | i++; 24 | } 25 | assert_equal(i, 5); 26 | } 27 | 28 | script repeat_number_variable() { 29 | test_it("repeat(var)"); 30 | var i = 0; 31 | var count = 5; 32 | repeat(count) { 33 | i++; 34 | } 35 | assert_equal(i, 5); 36 | } 37 | 38 | script repeat_string_variable() { 39 | test_it("repeat(string)"); 40 | var i = 0; 41 | var s = "moo"; 42 | repeat(s) { 43 | i++; 44 | } 45 | } 46 | 47 | script repeat_break() { 48 | test_it("repeat(i) { break; }"); 49 | var i = 0; 50 | repeat(5) { 51 | if(++i == 3) 52 | break; 53 | } 54 | assert_equal(i, 3); 55 | } 56 | 57 | script repeat_continue() { 58 | test_it("repeat(i) { continue; }"); 59 | var i = 0; 60 | var total = 0; 61 | repeat(5) { 62 | i++; 63 | continue; 64 | total++; 65 | } 66 | assert_equal(total, 0); 67 | } 68 | } -------------------------------------------------------------------------------- /TaffyScript/TsValue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript 8 | { 9 | /// 10 | /// Represents a weakly typed TaffyScript value. 11 | /// 12 | public interface ITsValue 13 | { 14 | object WeakValue { get; } 15 | } 16 | 17 | /// 18 | /// Represents a stringly type TaffyScript value. 19 | /// 20 | /// 21 | public interface ITsValue : ITsValue 22 | { 23 | T StrongValue { get; } 24 | } 25 | 26 | /// 27 | /// Wraps an immutable TaffyScript value. 28 | /// 29 | /// I.E. numbers, strings, and delegates. 30 | /// 31 | /// 32 | /// 33 | public struct TsImmutableValue : ITsValue 34 | { 35 | public T StrongValue { get; } 36 | public object WeakValue => StrongValue; 37 | 38 | public TsImmutableValue(T value) 39 | { 40 | StrongValue = value; 41 | } 42 | 43 | public override int GetHashCode() 44 | { 45 | return StrongValue.GetHashCode(); 46 | } 47 | } 48 | 49 | /// 50 | /// Wraps a mutable TaffyScript value. 51 | /// 52 | /// I.E. arrays. 53 | /// 54 | /// 55 | /// 56 | public class TsMutableValue : ITsValue 57 | { 58 | public T StrongValue { get; set; } 59 | public object WeakValue => StrongValue; 60 | 61 | public TsMutableValue(T value) 62 | { 63 | StrongValue = value; 64 | } 65 | 66 | public override int GetHashCode() 67 | { 68 | return StrongValue.GetHashCode(); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Samples/Threading/TaffyScript.Threading.Tests/threading_tests.tfs: -------------------------------------------------------------------------------- 1 | using TaffyScript.Threading; 2 | 3 | namespace TaffyScript.Threading.Tests { 4 | script main { 5 | print("Threading without locks") 6 | task_run(print_thread_id); 7 | task_run(print_thread_id); 8 | thread_sleep(500); 9 | print("\nFinished!\n"); 10 | 11 | var key = new ThreadLock(); 12 | var callback = script { print_thread_id_locked(key); } 13 | print("Threading with locks"); 14 | task_run(callback); 15 | task_run(callback); 16 | thread_sleep(500); 17 | print("Finished\n"); 18 | 19 | print("Starting thread that has a result:"); 20 | var task = task_run(script_with_result); 21 | var result = task.result; 22 | print_thread_result(result); 23 | 24 | print("\nStarting thread that throws an exception:") 25 | task = thread_start(script_with_exception); 26 | result = task.result; 27 | print_thread_result(result); 28 | } 29 | 30 | script print_thread_id() { 31 | for(var i = 0; i < 10; i++) { 32 | print(thread_get_id()); 33 | thread_sleep(1); 34 | } 35 | } 36 | 37 | script print_thread_id_locked(key) { 38 | key.lock(); 39 | for(var i = 0; i < 10; i++) { 40 | print(thread_get_id()); 41 | thread_sleep(1); 42 | } 43 | print(""); 44 | key.unlock(); 45 | } 46 | 47 | script script_with_result() { 48 | return 1; 49 | } 50 | 51 | script script_with_exception() { 52 | show_error("Thread " + string(thread_get_id()) + " threw an error", true); 53 | } 54 | 55 | script print_thread_result(result) { 56 | if(result.exception != "") 57 | print("Thread Failed: " + result.exception); 58 | else 59 | print("Thread Result: " + string(result.value)); 60 | } 61 | } -------------------------------------------------------------------------------- /TaffyScript.CommandLine/ErrorLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using TaffyScript.Compiler; 7 | 8 | namespace TaffyScript.CommandLine 9 | { 10 | public class ErrorLogger : IErrorLogger 11 | { 12 | public List Errors { get; } = new List(); 13 | public List Warnings { get; } = new List(); 14 | 15 | public void Error(string message) 16 | { 17 | Errors.Add(message); 18 | } 19 | 20 | public void Error(string message, TokenPosition position) 21 | { 22 | if(position != null) 23 | { 24 | var sb = new StringBuilder(message); 25 | if(position.File != null) 26 | { 27 | sb.Append(" in file "); 28 | sb.Append(position.File); 29 | } 30 | sb.Append(" at line "); 31 | sb.Append(position.Line); 32 | sb.Append(", column "); 33 | sb.Append(position.Column); 34 | message = sb.ToString(); 35 | } 36 | Errors.Add(message); 37 | } 38 | 39 | public void Warning(string message) 40 | { 41 | Warnings.Add(message); 42 | } 43 | 44 | public void Warning(string message, TokenPosition position) 45 | { 46 | if (position != null) 47 | { 48 | var sb = new StringBuilder(message); 49 | if (position.File != null) 50 | { 51 | sb.Append(" in file "); 52 | sb.Append(position.File); 53 | } 54 | sb.Append(" at line "); 55 | sb.Append(position.Line); 56 | sb.Append(", column "); 57 | sb.Append(position.Column); 58 | message = sb.ToString(); 59 | } 60 | Warnings.Add(message); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /TaffyScript/TsInstance.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using TaffyScript.Collections; 7 | using MethodImpl = System.Runtime.CompilerServices.MethodImplAttribute; 8 | using MethodImplOptions = System.Runtime.CompilerServices.MethodImplOptions; 9 | 10 | namespace TaffyScript 11 | { 12 | public abstract class TsInstance : ITsInstance 13 | { 14 | public static readonly DynamicInstance Global = new DynamicInstance("global"); 15 | public static ITsInstance Other { get; set; } 16 | 17 | internal protected Dictionary _members = new Dictionary(); 18 | 19 | public TsObject this[string memberName] 20 | { 21 | get => GetMember(memberName); 22 | set => _members[memberName] = value; 23 | } 24 | 25 | public abstract string ObjectType { get; } 26 | 27 | public TsObject Call(string scriptName, params TsObject[] args) 28 | { 29 | if (TryGetDelegate(scriptName, out var del)) 30 | return del.Invoke(args); 31 | 32 | throw new MemberAccessException(); 33 | } 34 | 35 | public TsDelegate GetDelegate(string scriptName) 36 | { 37 | if (TryGetDelegate(scriptName, out var del)) 38 | return del; 39 | 40 | throw new MemberAccessException(); 41 | } 42 | 43 | public TsObject GetMember(string memberName) 44 | { 45 | if (_members.TryGetValue(memberName, out var member)) 46 | return member; 47 | if (TryGetDelegate(memberName, out var del)) 48 | return del; 49 | throw new MemberAccessException(); 50 | } 51 | 52 | public void SetMember(string memberName, TsObject value) 53 | { 54 | _members[memberName] = value; 55 | } 56 | 57 | public override string ToString() 58 | { 59 | return ObjectType; 60 | } 61 | 62 | public abstract bool TryGetDelegate(string delegateName, out TsDelegate del); 63 | } 64 | } -------------------------------------------------------------------------------- /Samples/Moddable/Moddable.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27323.2 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moddable", "Moddable\Moddable.csproj", "{C3E9CCDE-C338-42BD-8F87-03699FE0DC08}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModdableExtern", "ModdableExtern\ModdableExtern.csproj", "{A4B77AD8-18D2-41C4-8B0F-FDF39E2EBC32}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Debug|x86 = Debug|x86 14 | Release|Any CPU = Release|Any CPU 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {C3E9CCDE-C338-42BD-8F87-03699FE0DC08}.Debug|Any CPU.ActiveCfg = Debug|x86 19 | {C3E9CCDE-C338-42BD-8F87-03699FE0DC08}.Debug|x86.ActiveCfg = Debug|x86 20 | {C3E9CCDE-C338-42BD-8F87-03699FE0DC08}.Debug|x86.Build.0 = Debug|x86 21 | {C3E9CCDE-C338-42BD-8F87-03699FE0DC08}.Release|Any CPU.ActiveCfg = Release|x86 22 | {C3E9CCDE-C338-42BD-8F87-03699FE0DC08}.Release|x86.ActiveCfg = Release|x86 23 | {C3E9CCDE-C338-42BD-8F87-03699FE0DC08}.Release|x86.Build.0 = Release|x86 24 | {A4B77AD8-18D2-41C4-8B0F-FDF39E2EBC32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {A4B77AD8-18D2-41C4-8B0F-FDF39E2EBC32}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {A4B77AD8-18D2-41C4-8B0F-FDF39E2EBC32}.Debug|x86.ActiveCfg = Debug|Any CPU 27 | {A4B77AD8-18D2-41C4-8B0F-FDF39E2EBC32}.Debug|x86.Build.0 = Debug|Any CPU 28 | {A4B77AD8-18D2-41C4-8B0F-FDF39E2EBC32}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {A4B77AD8-18D2-41C4-8B0F-FDF39E2EBC32}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {A4B77AD8-18D2-41C4-8B0F-FDF39E2EBC32}.Release|x86.ActiveCfg = Release|Any CPU 31 | {A4B77AD8-18D2-41C4-8B0F-FDF39E2EBC32}.Release|x86.Build.0 = Release|Any CPU 32 | EndGlobalSection 33 | GlobalSection(SolutionProperties) = preSolution 34 | HideSolutionNode = FALSE 35 | EndGlobalSection 36 | GlobalSection(ExtensibilityGlobals) = postSolution 37 | SolutionGuid = {1936E3B6-4538-49B6-BD29-A9D4BE10D649} 38 | EndGlobalSection 39 | EndGlobal 40 | -------------------------------------------------------------------------------- /TaffyScript/DynamicInstance.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript 8 | { 9 | public class DynamicInstance : ITsInstance 10 | { 11 | internal Dictionary _members = new Dictionary(); 12 | 13 | public TsObject this[string memberName] 14 | { 15 | get => _members[memberName]; 16 | set => _members[memberName] = value; 17 | } 18 | 19 | public string ObjectType { get; } 20 | 21 | public DynamicInstance(string typeName) 22 | { 23 | ObjectType = typeName; 24 | } 25 | 26 | public TsObject Call(string scriptName, params TsObject[] args) 27 | { 28 | if (TryGetDelegate(scriptName, out var del)) 29 | return del.Invoke(args); 30 | 31 | throw new MemberAccessException(); 32 | } 33 | 34 | public TsDelegate GetDelegate(string delegateName) 35 | { 36 | if (TryGetDelegate(delegateName, out var del)) 37 | return del; 38 | 39 | throw new MemberAccessException(); 40 | } 41 | 42 | public TsObject GetMember(string name) 43 | { 44 | return _members[name]; 45 | } 46 | 47 | public void SetMember(string name, TsObject value) 48 | { 49 | _members[name] = value; 50 | } 51 | 52 | public bool TryGetDelegate(string delegateName, out TsDelegate del) 53 | { 54 | if (_members.TryGetValue(delegateName, out var member) && member.Type == VariableType.Delegate) 55 | { 56 | del = member.GetDelegateUnchecked(); 57 | return true; 58 | } 59 | 60 | del = null; 61 | return false; 62 | } 63 | 64 | public static implicit operator TsObject(DynamicInstance instance) 65 | { 66 | return new TsObject(instance); 67 | } 68 | 69 | public static explicit operator DynamicInstance(TsObject obj) 70 | { 71 | return (DynamicInstance)obj.Value.WeakValue; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/Content/font.spritefont: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 14 | Arial 15 | 16 | 20 | 12 21 | 22 | 26 | 0 27 | 28 | 32 | true 33 | 34 | 38 | 39 | 40 | 44 | 45 | 46 | 53 | 54 | 55 | 56 | ~ 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/with.tfs: -------------------------------------------------------------------------------- 1 | using UnitTest; 2 | using TaffyScript.Collections; 3 | 4 | namespace LanguageTests { 5 | script run_with_tests() { 6 | var tests = new obj_unit_test("With Tests", 7 | with_can_compile, 8 | with_can_access_local_ts, 9 | with_can_access_local_cs, 10 | with_can_call_event_ts, 11 | with_can_call_event_cs, 12 | with_sets_other); 13 | tests.run_tests(); 14 | } 15 | 16 | script with_can_compile() { 17 | test_it("with(ts)"); 18 | var obj = new obj_with(0); 19 | with(obj) { 20 | var i = 0; 21 | } 22 | } 23 | 24 | script with_can_access_local_ts() { 25 | test_it("with(ts) local"); 26 | var obj = new obj_with(2); 27 | with(obj) { 28 | assert_equal(num, 2); 29 | } 30 | } 31 | 32 | script with_can_access_local_cs() { 33 | test_it("with(cs) local"); 34 | var list = new List(); 35 | list.add(3); 36 | with(list) { 37 | assert_equal(count, 1); 38 | } 39 | } 40 | 41 | script with_can_call_event_ts() { 42 | test_it("with(ts) event()"); 43 | var obj = new obj_with(2); 44 | with(obj) { 45 | assert_equal(get_value(), 4); 46 | } 47 | } 48 | 49 | script with_can_call_event_cs() { 50 | test_it("with(cs) event()"); 51 | var list = new List(); 52 | with(list) { 53 | add(4, 3); 54 | } 55 | assert_equal(list.count, 2); 56 | } 57 | 58 | script with_sets_other() { 59 | test_it("with(ts) other.val"); 60 | var obj2 = new obj_with(2); 61 | var obj3 = new obj_with(3); 62 | with(obj2) { 63 | with(obj3) { 64 | assert_equal(other.num, 2); 65 | assert_equal(num, 3); 66 | } 67 | } 68 | } 69 | 70 | object obj_with { 71 | script create(num) { 72 | self.num = num; 73 | } 74 | 75 | script get_value() { 76 | return 4; 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /TaffyScript.Compiler/Syntax/ISyntaxElementVisitor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript.Compiler.Syntax 8 | { 9 | public interface ISyntaxElementVisitor 10 | { 11 | void Visit(AdditiveNode additive); 12 | void Visit(ArgumentAccessNode argumentAccess); 13 | void Visit(ArrayAccessNode arrayAccess); 14 | void Visit(ArrayLiteralNode arrayLiteral); 15 | void Visit(AssignNode assign); 16 | void Visit(BaseNode baseNode); 17 | void Visit(BitwiseNode bitwise); 18 | void Visit(BlockNode block); 19 | void Visit(BreakToken breakToken); 20 | void Visit(ConditionalNode conditional); 21 | void Visit(IConstantToken constantToken); 22 | void Visit(ContinueToken continueToken); 23 | void Visit(DoNode @do); 24 | void Visit(EndToken endToken); 25 | void Visit(EnumNode enumDeclaration); 26 | void Visit(EqualityNode equality); 27 | void Visit(ForNode @for); 28 | void Visit(FunctionCallNode functionCall); 29 | void Visit(IfNode @if); 30 | void Visit(ImportObjectNode importObjectNode); 31 | void Visit(ImportScriptNode import); 32 | void Visit(LambdaNode lambdaNode); 33 | void Visit(LocalsNode locals); 34 | void Visit(LogicalNode logical); 35 | void Visit(MemberAccessNode memberAccess); 36 | void Visit(MultiplicativeNode multiplicative); 37 | void Visit(NamespaceNode namespaceNode); 38 | void Visit(NewNode newNode); 39 | void Visit(ObjectNode objectNode); 40 | void Visit(PostfixNode postfix); 41 | void Visit(PrefixNode prefix); 42 | void Visit(ReadOnlyToken readOnlyToken); 43 | void Visit(RelationalNode relational); 44 | void Visit(RepeatNode repeatNode); 45 | void Visit(ReturnNode @return); 46 | void Visit(RootNode root); 47 | void Visit(ScriptNode script); 48 | void Visit(ShiftNode shift); 49 | void Visit(SwitchNode @switch); 50 | void Visit(UsingsNode usingsNode); 51 | void Visit(VariableToken variableToken); 52 | void Visit(WhileNode @while); 53 | void Visit(WithNode withNode); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /TaffyScript/ITsInstance.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript 8 | { 9 | /// 10 | /// Represents an instance of an object in TaffyScript. 11 | /// 12 | public interface ITsInstance 13 | { 14 | 15 | /// 16 | /// Gets or sets a value based on a variable name. 17 | /// 18 | /// The name of the variable 19 | /// 20 | TsObject this[string memberName] { get; set; } 21 | 22 | /// 23 | /// Gets the type of this instance. 24 | /// 25 | string ObjectType { get; } 26 | 27 | /// 28 | /// Gets the value of a member from this instance. 29 | /// 30 | /// The name of the member. 31 | /// 32 | TsObject GetMember(string name); 33 | 34 | /// 35 | /// Sets the value of a member on this instance. 36 | /// 37 | /// The name of the member. 38 | /// The new value. 39 | void SetMember(string name, TsObject value); 40 | 41 | /// 42 | /// Gets a delegate defined by this instance. 43 | /// 44 | /// The name of the delegate. 45 | /// If found, the delegate. 46 | /// True if found, false otherwise. 47 | bool TryGetDelegate(string delegateName, out TsDelegate del); 48 | 49 | /// 50 | /// Gets a delegate defined by this instance. 51 | /// 52 | /// The name of the delegate. 53 | /// 54 | TsDelegate GetDelegate(string delegateName); 55 | 56 | /// 57 | /// Calls a script defined or assigned to the instance. 58 | /// 59 | /// The name of the script to call. 60 | /// Any arguments to pass to the script. 61 | /// Script result. 62 | TsObject Call(string scriptName, params TsObject[] args); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/SelectState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Microsoft.Xna.Framework; 7 | using Microsoft.Xna.Framework.Content; 8 | using Microsoft.Xna.Framework.Graphics; 9 | using Microsoft.Xna.Framework.Input; 10 | using ModdableExtern; 11 | using TaffyScript; 12 | 13 | namespace Moddable 14 | { 15 | public class SelectState : IGameState 16 | { 17 | private SpriteFont _font; 18 | private int _selected = 0; 19 | private List _characterChoices = new List(); 20 | private Game1 _game; 21 | 22 | public SelectState(Game1 game, ContentManager content) 23 | { 24 | _font = content.Load("font"); 25 | foreach(var type in TsInstance.Types) 26 | { 27 | if (TsInstance.ObjectIsAncestor(type, "GameBase.par_character_select")) 28 | _characterChoices.Add(new PlayerSelect(type)); 29 | } 30 | _game = game; 31 | } 32 | 33 | public void Draw(SpriteBatch batch) 34 | { 35 | for(var i = 0; i < _characterChoices.Count; i++) 36 | { 37 | var color = i == _selected ? Color.Red : Color.Black; 38 | batch.DrawString(_font, _characterChoices[i].Name, new Vector2(32, 32 + i * 20), color); 39 | } 40 | } 41 | 42 | public void Update(GameTime gameTime) 43 | { 44 | if(Input.KeyCheckPressed(Keys.Up)) 45 | { 46 | if (_selected == 0) 47 | _selected = _characterChoices.Count - 1; 48 | else 49 | --_selected; 50 | } 51 | else if (Input.KeyCheckPressed(Keys.Down)) 52 | { 53 | if (_selected == _characterChoices.Count - 1) 54 | _selected = 0; 55 | else 56 | ++_selected; 57 | } 58 | else if (Input.KeyCheckPressed(Keys.Space)) 59 | { 60 | var type = _characterChoices[_selected].PlayerObjectType; 61 | foreach (var choice in _characterChoices) 62 | choice.Destroy(); 63 | var play = new PlayState(type, _game.Content); 64 | _game.ChangeState(play); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Samples/TestSuite/TaffyScript.Tests/TaffyScript.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0C33B274-4C13-4F74-9A4C-83C3ADB82408} 8 | Library 9 | Properties 10 | TaffyScript.Tests 11 | TaffyScript.Tests 12 | v4.5.2 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | ..\..\..\TaffyScript\bin\Release\TaffyScript.dll 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Samples/Moddable/ModdableExtern/ModdableExtern.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {A4B77AD8-18D2-41C4-8B0F-FDF39E2EBC32} 8 | Library 9 | Properties 10 | ModdableExtern 11 | ModdableExtern 12 | v4.5.2 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\MonoGame.Framework.Portable.3.6.0.1625\lib\portable-net45+win8+wpa81\MonoGame.Framework.dll 35 | True 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /Samples/Threading/TaffyScript.Threading/TaffyScript.Threading.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3D25DE02-F1A9-47E0-B570-1DCF3882D7D4} 8 | Library 9 | Properties 10 | TaffyScript.Threading 11 | TaffyScript.Threading 12 | v4.5.2 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | {68399d06-20df-4ce8-9920-bd82df2b8f69} 53 | TaffyScript 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/lambda.tfs: -------------------------------------------------------------------------------- 1 | // Lambdas aren't implemented yet; 2 | // This file shows a potential implementation. 3 | // Currently it's excluded from the build. 4 | 5 | using UnitTest; 6 | 7 | namespace LanguageTests { 8 | script run_lambda_tests() { 9 | var tests = new obj_unit_test("Lambda Tests", 10 | lambda_no_capture, 11 | lambda_capture_local, 12 | lambda_capture_argument, 13 | lambda_capture_default_argument, 14 | lambda_argument, 15 | lambda_local, 16 | lambda_nested_lambda); 17 | 18 | tests.run_tests(); 19 | } 20 | 21 | script lambda_no_capture() { 22 | test_it("lambda { no_capture }"); 23 | var i = script { 24 | return 1 25 | } 26 | var result = i(); 27 | assert_equal(result, 1); 28 | } 29 | 30 | script lambda_capture_local() { 31 | test_it("lambda { local_capture }"); 32 | var i = 1; 33 | var s = script { 34 | return i; 35 | } 36 | var result = s(); 37 | assert_equal(result, 1); 38 | } 39 | 40 | script lambda_capture_argument() { 41 | test_it("lambda { arg_capture }"); 42 | var s = scr_get_arg_capture_script(1); 43 | var result = s(); 44 | assert_equal(result, 1); 45 | } 46 | 47 | script lambda_capture_default_argument() { 48 | test_it("lambda { arg_default_capture }"); 49 | var s = scr_get_arg_capture_script(); 50 | var result = s(); 51 | assert_equal(result, 2); 52 | } 53 | 54 | script lambda_argument() { 55 | test_it("lambda(arg) {}"); 56 | var s = script(arg) { 57 | return arg; 58 | } 59 | var result = s(2); 60 | assert_equal(result, 2); 61 | } 62 | 63 | script scr_get_arg_capture_script(arg = 2) { 64 | return script { return arg; } 65 | } 66 | 67 | script lambda_local() { 68 | test_it("lambda { var i = 0 }"); 69 | var s = script { 70 | var i = 1; 71 | return i; 72 | } 73 | var result = s(); 74 | assert_equal(result, 1); 75 | } 76 | 77 | script lambda_nested_lambda() { 78 | test_it("lambda { lambda {} }"); 79 | var s = scr_get_nested_lambda(); 80 | var result = s(); 81 | assert_equal(result, 3); 82 | } 83 | 84 | script scr_get_nested_lambda() { 85 | return script { 86 | var i = 2; 87 | var f = script { i++; } 88 | f(); 89 | return i; 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /TaffyScript.Compiler/DotNet/AssemblyLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | 7 | namespace TaffyScript.Compiler.DotNet 8 | { 9 | public class DotNetAssemblyLoader 10 | { 11 | private Dictionary _loadedAssemblies = new Dictionary(); 12 | private Dictionary> _namespaces = new Dictionary>(); 13 | 14 | /// 15 | /// Gets all of the currently loaded assemblies. 16 | /// 17 | public Dictionary LoadedAssemblies => _loadedAssemblies; 18 | 19 | /// 20 | /// Gets a dictionary that maps namespaces to the assemblies that define the namespace. 21 | /// 22 | public Dictionary> Namespaces => _namespaces; 23 | 24 | /// 25 | /// Creates a new and loads all of the given assembly files. 26 | /// 27 | /// 28 | public DotNetAssemblyLoader(params string[] assemblies) 29 | { 30 | foreach (var asm in assemblies) 31 | LoadAssembly(asm); 32 | } 33 | 34 | /// 35 | /// Loads an assembly from a file and returns the result. 36 | /// 37 | /// The path to an assembly file. 38 | public Assembly LoadAssembly(string asmPath) 39 | { 40 | if (_loadedAssemblies.ContainsKey(asmPath)) 41 | { 42 | throw new InvalidOperationException($"Duplicate assembly found: {asmPath}"); 43 | } 44 | 45 | var asm = Assembly.LoadFrom(asmPath); 46 | 47 | InitializeAssembly(asm); 48 | 49 | return asm; 50 | } 51 | 52 | /// 53 | /// Initializes a loaded assembly. 54 | /// 55 | /// If the assembly was loaded via the LoadAssembly method, do not call this method. 56 | /// 57 | /// 58 | /// 59 | public void InitializeAssembly(Assembly asm) 60 | { 61 | _loadedAssemblies[asm.GetName().Name] = asm; 62 | var namespaces = asm.GetExportedTypes() 63 | .Select(t => t.Namespace) 64 | .Where(t => t != null) 65 | .Distinct(); 66 | 67 | foreach (var ns in namespaces) 68 | { 69 | if (!_namespaces.ContainsKey(ns)) 70 | _namespaces.Add(ns, new List()); 71 | 72 | _namespaces[ns].Add(asm); 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Samples/TestSuite/TaffyScript.Tests/TestHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using TaffyScript; 8 | 9 | namespace TaffyScript.Tests 10 | { 11 | public static class TestHelper 12 | { 13 | [WeakMethod] 14 | public static TsObject Try(ITsInstance target, TsObject[] args) 15 | { 16 | var del = (TsDelegate)args[0]; 17 | TsObject[] delArgs = null; 18 | if (args.Length > 1) 19 | { 20 | delArgs = new TsObject[args.Length - 1]; 21 | Array.Copy(args, 1, delArgs, 0, delArgs.Length); 22 | } 23 | 24 | var result = new DynamicInstance("obj_exception"); 25 | try 26 | { 27 | del.Invoke(delArgs); 28 | result["has_error"] = false; 29 | result["error_type"] = ""; 30 | result["error_msg"] = ""; 31 | } 32 | catch (Exception e) 33 | { 34 | result["has_error"] = true; 35 | result["error_type"] = e.GetType().Name; 36 | result["error_msg"] = e.Message; 37 | } 38 | 39 | return result; 40 | } 41 | 42 | [WeakMethod] 43 | public static TsObject TryExpect(ITsInstance target, TsObject[] args) 44 | { 45 | var del = (TsDelegate)args[0]; 46 | TsObject[] delArgs = null; 47 | if (args.Length > 2) 48 | { 49 | delArgs = new TsObject[args.Length - 2]; 50 | Array.Copy(args, 2, delArgs, 0, delArgs.Length); 51 | } 52 | 53 | try 54 | { 55 | del.Invoke(delArgs); 56 | } 57 | catch(Exception e) 58 | { 59 | return e.GetType().Name == (string)args[1]; 60 | } 61 | 62 | return false; 63 | } 64 | 65 | [WeakMethod] 66 | public static TsObject TimeInvoke(ITsInstance target, TsObject[] args) 67 | { 68 | var del = (TsDelegate)args[0]; 69 | TsObject[] delArgs = null; 70 | if(args.Length > 1) 71 | { 72 | delArgs = new TsObject[args.Length - 1]; 73 | Array.Copy(args, 1, delArgs, 0, delArgs.Length); 74 | } 75 | 76 | var timer = new Stopwatch(); 77 | timer.Start(); 78 | del.Invoke(delArgs); 79 | timer.Stop(); 80 | var result = new DynamicInstance("obj_timer_result"); 81 | result["ms"] = timer.ElapsedMilliseconds; 82 | result["ticks"] = timer.ElapsedTicks; 83 | return result; 84 | } 85 | 86 | public static void CollectGarbage() 87 | { 88 | GC.Collect(); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Samples/Threading/TaffyScript.Threading/Tasks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using RealTask = System.Threading.Tasks.Task; 8 | 9 | namespace TaffyScript.Threading 10 | { 11 | [WeakBaseType] 12 | public static class Tasks 13 | { 14 | [WeakMethod] 15 | public static TsObject task_run(ITsInstance inst, TsObject[] args) 16 | { 17 | return args.Length == 1 18 | ? new Task(RealTask.Run(() => args[0].GetDelegate().Invoke())) 19 | : new Task(RealTask.Run(() => args[0].GetDelegate().Invoke(), ((TaskCancellationToken)args[1]).Source.Token)); 20 | } 21 | 22 | [WeakMethod] 23 | public static TsObject task_wait_all(ITsInstance inst, TsObject[] args) 24 | { 25 | var tasks = new RealTask[args.Length]; 26 | for (var i = 0; i < tasks.Length; i++) 27 | tasks[i] = ((Task)args[i]).Source; 28 | 29 | try 30 | { 31 | RealTask.WaitAll(tasks); 32 | return ""; 33 | } 34 | catch(AggregateException e) 35 | { 36 | return e.InnerException.ToString(); 37 | } 38 | } 39 | 40 | [WeakMethod] 41 | public static TsObject task_wait_any(ITsInstance inst, TsObject[] args) 42 | { 43 | var tasks = new RealTask[args.Length]; 44 | for (var i = 0; i < tasks.Length; i++) 45 | tasks[i] = ((Task)args[i]).Source; 46 | 47 | try 48 | { 49 | var result = RealTask.WaitAny(tasks); 50 | return CreateTaskResult(result, ""); 51 | } 52 | catch(AggregateException e) 53 | { 54 | return CreateTaskResult(-1, e.InnerException.ToString()); 55 | } 56 | } 57 | 58 | [WeakMethod] 59 | public static TsObject thread_pool_queue_item(ITsInstance inst, TsObject[] args) 60 | { 61 | return ThreadPool.QueueUserWorkItem((obj) => args[0].GetDelegate().Invoke()); 62 | } 63 | 64 | [WeakMethod] 65 | public static TsObject thread_sleep(ITsInstance inst, TsObject[] args) 66 | { 67 | Thread.Sleep((int)args[0]); 68 | return TsObject.Empty(); 69 | } 70 | 71 | [WeakMethod] 72 | public static TsObject thread_get_id(ITsInstance inst, TsObject[] args) 73 | { 74 | return Thread.CurrentThread.ManagedThreadId; 75 | } 76 | 77 | public static TsObject CreateTaskResult(TsObject result, string exception) 78 | { 79 | var inst = new DynamicInstance("TaffyScript.Threading.TaskResult"); 80 | inst["value"] = result; 81 | inst["exception"] = exception; 82 | return inst; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /TaffyScript.CommandLine/TaffyScript.CommandLine.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {FF4BC25B-646A-4849-BFC1-4731CEC9D456} 8 | Exe 9 | TaffyScript.CommandLine 10 | tsc 11 | v4.5.2 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\packages\NDesk.Options.0.2.1\lib\NDesk.Options.dll 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {4022f406-fce6-4a8d-b99f-6ef6c406248a} 59 | TaffyScript.Compiler 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Samples/Threading/TaffyScript.Threading/ThreadLock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | 7 | namespace TaffyScript.Threading 8 | { 9 | [WeakObject] 10 | public class ThreadLock : ITsInstance 11 | { 12 | private object _key = new object(); 13 | 14 | public TsObject this[string memberName] 15 | { 16 | get => GetMember(memberName); 17 | set => SetMember(memberName, value); 18 | } 19 | 20 | public string ObjectType => "TaffyScript.Threading.ThreadLock"; 21 | 22 | public ThreadLock(TsObject[] args) 23 | { 24 | } 25 | 26 | public TsObject Call(string scriptName, params TsObject[] args) 27 | { 28 | switch(scriptName) 29 | { 30 | case "lock": 31 | return _lock(null, null); 32 | case "unlock": 33 | return unlock(null, null); 34 | case "try_lock": 35 | return try_lock(null, args); 36 | default: 37 | throw new MissingMethodException(ObjectType, scriptName); 38 | } 39 | } 40 | 41 | public TsDelegate GetDelegate(string delegateName) 42 | { 43 | if (TryGetDelegate(delegateName, out var del)) 44 | return del; 45 | throw new MissingMethodException(ObjectType, delegateName); 46 | } 47 | 48 | public TsObject GetMember(string name) 49 | { 50 | if (TryGetDelegate(name, out var del)) 51 | return del; 52 | throw new MissingMemberException(ObjectType, name); 53 | } 54 | 55 | public void SetMember(string name, TsObject value) 56 | { 57 | throw new MissingMemberException(ObjectType, name); 58 | } 59 | 60 | public bool TryGetDelegate(string delegateName, out TsDelegate del) 61 | { 62 | switch (delegateName) 63 | { 64 | case "lock": 65 | del = new TsDelegate(_lock, "lock", this); 66 | return true; 67 | case "unlock": 68 | del = new TsDelegate(unlock, "unlock", this); 69 | return true; 70 | case "try_lock": 71 | del = new TsDelegate(try_lock, "try_lock", this); 72 | return true; 73 | default: 74 | del = null; 75 | return false; 76 | } 77 | } 78 | 79 | private TsObject _lock(ITsInstance inst, TsObject[] args) 80 | { 81 | Monitor.Enter(_key); 82 | return TsObject.Empty(); 83 | } 84 | 85 | private TsObject unlock(ITsInstance inst, TsObject[] args) 86 | { 87 | Monitor.Exit(_key); 88 | return TsObject.Empty(); 89 | } 90 | 91 | private TsObject try_lock(ITsInstance inst, TsObject[] args) 92 | { 93 | return args != null && args.Length > 0 ? Monitor.TryEnter(_key, (int)args[0]) : Monitor.TryEnter(_key); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TaffyScript 2 | ## What is TaffyScript? 3 | TaffyScript is a dynamic programming language designed to be embedded into .NET applications. The primary purpose of the language is to be used for implementing game logic, and for the easy addition of mod support. However, it can be used as a general purpose language if desired. Originally it was based off of the [GameMaker Language](https://docs.yoyogames.com/source/dadiospice/002_reference/001_gml%20language%20overview/), but it no longer bears much resemblance. For more info, check out the [wiki](https://github.com/mystborn/TaffyScript/wiki). 4 | 5 | ## Nuget 6 | Both the TaffyScript implementation and it's base class library are available via nuget: 7 | * https://www.nuget.org/packages/TaffyScript/ 8 | * https://www.nuget.org/packages/TaffyScript.BCL/ 9 | 10 | You can use these to use TaffyScript projects inside of .NET projects 11 | 12 | ## Features 13 | * Built in C# 14 | * Compiles into a valid .NET assembly 15 | * Dynamic Typing 16 | * Does not use DLR 17 | * Accessable from existing .NET projects 18 | * Import external .NET methods and types 19 | * Basic Reflection 20 | 21 | ## Sounds Great! How Can I Get it? 22 | You can now download a precompiled binary from the [releases](https://github.com/mystborn/TaffyScript/releases) page! Please note that TaffyScript is windows only. 23 | 24 | ## Example Code 25 | ```cs 26 | script main { 27 | print("Hello, World!"); 28 | var user = new User("Script"); 29 | print_user(user); 30 | user.name = "Taffy"; 31 | print_user(user); 32 | print("Closing..."); 33 | } 34 | 35 | script print_user(user) { 36 | print("User: " + user.name); 37 | } 38 | 39 | object User { 40 | script create(name) { 41 | self.name = ""; 42 | } 43 | 44 | script greet { 45 | print("Hello, " + name); 46 | } 47 | } 48 | 49 | // Output: 50 | // Hello World! 51 | // User: Script 52 | // User: Taffy 53 | // Closing... 54 | ``` 55 | 56 | ## Want to contribute? 57 | Occasionally I'll add issues with the `opinion wanted` label. These are issues asking about new features or language changes that I want some additional feedback on. The easiest way to contribute is to comment on those. 58 | 59 | Alternatively, I have a very, _very_, rough draft of my plans for the language on [this](https://trello.com/b/suLDsBDJ/taffyscript) Trello board. If you want to pick anything up from that, it would certainly be a big help. If you have any further questions, you can ask me on Discord (I prefer this way, as I'm almost always online). My username is mystborn#0264. Alternatively, you can shoot me an email at ckramer017@gmail.com, but I don't check it as often as I should. 60 | 61 | ## General Roadmap 62 | The following are some general things I'd like to add to the language at some point in the future. A slightly more detailed roadmap can be found on the [trello](https://trello.com/b/suLDsBDJ/taffyscript) page. 63 | 64 | * Documentation Website (High Priority) 65 | * Just a general github pages site detailing how to use the language as well as major library documentation 66 | * Tests 67 | * Currently the tests make sure certain things work, but a larger set of tests is needed to make sure things _break in the right way_. 68 | * Runtime Interpreter 69 | * Base Class Library 70 | * The BCL is extremely barebones currently. For example, it doesn't have any file handling, date/time handling, or networking scripts. 71 | -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/math.tfs: -------------------------------------------------------------------------------- 1 | // This file contains tests for most of the math scripts. 2 | // That includes scripts related to the rng seed. 3 | // The actual rng relies on c#, but it wouldn't hurt to test some it's functionality 4 | // In addition, I wasn't sure how to test some the log related functions: 5 | // * ln 6 | // * log10 7 | // * logn 8 | // * exp 9 | 10 | using UnitTest; 11 | 12 | namespace LanguageTests { 13 | script run_math_tests() { 14 | var tests = new obj_unit_test("Math Tests", 15 | math_abs, 16 | math_ceil, 17 | math_choose, 18 | math_clamp_none, 19 | math_clamp_min, 20 | math_clamp_max, 21 | math_floor, 22 | math_max, 23 | math_min, 24 | math_random_seed, 25 | math_round, 26 | math_sign, 27 | math_square, 28 | math_square_root); 29 | tests.run_tests(); 30 | } 31 | 32 | script math_abs() { 33 | test_it("abs()"); 34 | var i = -1; 35 | assert_equal(abs(i), 1); 36 | i = 2; 37 | assert_equal(abs(i), 2); 38 | } 39 | 40 | script math_ceil() { 41 | test_it("ceil()"); 42 | var i = 1.2; 43 | assert_equal(ceil(i), 2); 44 | } 45 | 46 | script math_choose() { 47 | test_it("choose()"); 48 | var i = choose(2,4); 49 | assert(i == 2 || i == 4); 50 | } 51 | 52 | script math_clamp_none() { 53 | test_it("clamp() inclusive") 54 | var i = clamp(1, 0, 2); 55 | assert_equal(i, 1); 56 | } 57 | 58 | script math_clamp_min() { 59 | test_it("clamp() min"); 60 | var i = clamp(0, 3, 5); 61 | assert_equal(i, 3); 62 | } 63 | 64 | script math_clamp_max() { 65 | test_it("clamp() max"); 66 | var i = clamp(7, 3, 5); 67 | assert_equal(i, 5); 68 | } 69 | 70 | script math_floor() { 71 | test_it("floor()"); 72 | var i = floor(2.7); 73 | assert_equal(i, 2); 74 | } 75 | 76 | script math_max() { 77 | test_it("max()"); 78 | var i = max(1, 9, 2, 3, 5); 79 | assert_equal(i, 9); 80 | } 81 | 82 | script math_min() { 83 | test_it("min()"); 84 | var i = min(9, 2, 3, 5); 85 | assert_equal(i, 2); 86 | } 87 | 88 | script math_random_seed() { 89 | test_it("random_seed"); 90 | var seed = random_get_seed(); 91 | assert_equal(seed, 123456789); 92 | random_set_seed(987654321); 93 | seed = random_get_seed(); 94 | assert_equal(seed, 987654321); 95 | seed = randomise(); 96 | assert_equal(random_get_seed(), seed); 97 | } 98 | 99 | script math_round() { 100 | test_it("round()"); 101 | var i = round(1.5); 102 | assert_equal(i, 2); 103 | i = round(3.49); 104 | assert_equal(i, 3); 105 | } 106 | 107 | script math_sign() { 108 | test_it("sign()"); 109 | var i = sign(4); 110 | assert_equal(i, 1); 111 | i = sign(-4); 112 | assert_equal(i, -1); 113 | i = sign(0); 114 | assert_equal(i, 0); 115 | } 116 | 117 | script math_square() { 118 | test_it("sqr()"); 119 | var i = sqr(9); 120 | assert_equal(i, 81); 121 | } 122 | 123 | script math_square_root() { 124 | test_it("sqrt()"); 125 | var i = sqrt(9); 126 | assert_equal(i, 3); 127 | } 128 | } -------------------------------------------------------------------------------- /TaffyScript/TaffyScript.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {68399D06-20DF-4CE8-9920-BD82DF2B8F69} 8 | Library 9 | Properties 10 | TaffyScript 11 | TaffyScript 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | true 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | bin\Release\TaffyScript.xml 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /TaffyScript/TsDelegate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TaffyScript 8 | { 9 | /// 10 | /// Represents a TaffyScript script. 11 | /// 12 | /// The target of the script. 13 | /// The script arguments. 14 | /// The scripts result. 15 | public delegate TsObject TsScript(ITsInstance target, TsObject[] args); 16 | 17 | /// 18 | /// Language friendly wrapper over a . 19 | /// 20 | public class TsDelegate : IEquatable 21 | { 22 | /// 23 | /// A wrapped TaffyScript script. 24 | /// 25 | public TsScript Script { get; private set; } 26 | 27 | /// 28 | /// The target of the wrapped script. 29 | /// 30 | public ITsInstance Target { get; private set; } 31 | 32 | /// 33 | /// The name of the wrapped script. 34 | /// 35 | public string Name { get; } 36 | 37 | public TsDelegate(TsScript script, string name) 38 | { 39 | Target = null; 40 | Script = script; 41 | Name = name; 42 | } 43 | 44 | public TsDelegate(TsScript script, string name, ITsInstance target) 45 | { 46 | Target = target; 47 | Script = script; 48 | Name = name; 49 | } 50 | 51 | /// 52 | /// Creates a copy of a TsDelegate with a new target. 53 | /// 54 | /// 55 | /// 56 | public TsDelegate(TsDelegate original, ITsInstance target) 57 | { 58 | Script = original.Script; 59 | Name = original.Name; 60 | Target = target; 61 | } 62 | 63 | /// 64 | /// Invokes the wrapped script with the given arguments. 65 | /// 66 | /// 67 | /// 68 | public TsObject Invoke(params TsObject[] args) 69 | { 70 | // If the script needs a target, get it from the first index of the args array. 71 | // This will make it easier to invoke Delegates from TS. 72 | 73 | return Script(Target, args); 74 | } 75 | 76 | /// 77 | /// Invokes the wrapped script with the specified target and arguments. 78 | /// 79 | /// 80 | /// 81 | /// 82 | public TsObject Invoke(ITsInstance target, params TsObject[] args) 83 | { 84 | return Script(target, args); 85 | } 86 | 87 | public override bool Equals(object obj) 88 | { 89 | if (obj is TsDelegate del) 90 | return Equals(del); 91 | return false; 92 | } 93 | 94 | public bool Equals(TsDelegate other) 95 | { 96 | if (other is null) 97 | return false; 98 | return Script == other.Script && Target == other.Target; 99 | } 100 | 101 | public override int GetHashCode() 102 | { 103 | return Script.GetHashCode(); 104 | } 105 | 106 | public override string ToString() 107 | { 108 | return Name; 109 | } 110 | 111 | public static bool operator ==(TsDelegate left, TsDelegate right) 112 | { 113 | if (!(left is null)) 114 | return left.Equals(right); 115 | else return right is null; 116 | } 117 | 118 | public static bool operator !=(TsDelegate left, TsDelegate right) 119 | { 120 | if (!(left is null)) 121 | return !left.Equals(right); 122 | else return !(right is null); 123 | } 124 | } 125 | } -------------------------------------------------------------------------------- /Samples/Moddable/Moddable/Game1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | using Microsoft.Xna.Framework; 7 | using Microsoft.Xna.Framework.Graphics; 8 | using Microsoft.Xna.Framework.Input; 9 | using ModdableExtern; 10 | using TaffyScript; 11 | 12 | namespace Moddable 13 | { 14 | /// 15 | /// This is the main type for your game. 16 | /// 17 | public class Game1 : Game 18 | { 19 | GraphicsDeviceManager graphics; 20 | SpriteBatch spriteBatch; 21 | IGameState _state; 22 | 23 | public Game1() 24 | { 25 | graphics = new GraphicsDeviceManager(this); 26 | Content.RootDirectory = "Content"; 27 | } 28 | 29 | public void ChangeState(IGameState state) 30 | { 31 | _state = state; 32 | } 33 | 34 | /// 35 | /// Allows the game to perform any initialization it needs to before starting to run. 36 | /// This is where it can query for any required services and load any non-graphic 37 | /// related content. Calling base.Initialize will enumerate through any components 38 | /// and initialize them as well. 39 | /// 40 | protected override void Initialize() 41 | { 42 | 43 | // If you were doing this for realsies, 44 | // You would use Mono.Cecil to view the Assembly level attributes to make sure they has the 45 | // WeakLibraryAttribute before loading it. 46 | 47 | TaffyScript.BCL.TaffyScript_BCL_Initializer.Initialize(); 48 | GameBase.GameBase_Initializer.Initialize(); 49 | 50 | if (File.Exists("mods.txt")) 51 | { 52 | using(var sr = new StreamReader("mods.txt")) 53 | { 54 | while (!sr.EndOfStream) 55 | { 56 | var mod = sr.ReadLine(); 57 | if (!mod.EndsWith(".dll")) 58 | mod += ".dll"; 59 | var path = Path.Combine(Directory.GetCurrentDirectory(), "mods", mod); 60 | if(File.Exists(path)) 61 | TaffyScriptLoader.Load(path); 62 | } 63 | } 64 | } 65 | 66 | base.Initialize(); 67 | } 68 | 69 | /// 70 | /// LoadContent will be called once per game and is the place to load 71 | /// all of your content. 72 | /// 73 | protected override void LoadContent() 74 | { 75 | // Create a new SpriteBatch, which can be used to draw textures. 76 | spriteBatch = new SpriteBatch(GraphicsDevice); 77 | ChangeState(new SelectState(this, Content)); 78 | } 79 | 80 | /// 81 | /// UnloadContent will be called once per game and is the place to unload 82 | /// game-specific content. 83 | /// 84 | protected override void UnloadContent() 85 | { 86 | 87 | } 88 | 89 | /// 90 | /// Allows the game to run logic such as updating the world, 91 | /// checking for collisions, gathering input, and playing audio. 92 | /// 93 | /// Provides a snapshot of timing values. 94 | protected override void Update(GameTime gameTime) 95 | { 96 | Input.Update(); 97 | 98 | if (_state != null) 99 | _state.Update(gameTime); 100 | 101 | base.Update(gameTime); 102 | } 103 | 104 | /// 105 | /// This is called when the game should draw itself. 106 | /// 107 | /// Provides a snapshot of timing values. 108 | protected override void Draw(GameTime gameTime) 109 | { 110 | GraphicsDevice.Clear(Color.CornflowerBlue); 111 | 112 | spriteBatch.Begin(samplerState: SamplerState.PointClamp); 113 | 114 | if (_state != null) 115 | _state.Draw(spriteBatch); 116 | 117 | spriteBatch.End(); 118 | 119 | base.Draw(gameTime); 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /TaffyScript.CommandLine/Program.cs: -------------------------------------------------------------------------------- 1 | using NDesk.Options; 2 | using System; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using TaffyScript.Compiler; 6 | using TaffyScript.Compiler.Backend; 7 | 8 | namespace TaffyScript.CommandLine 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | bool run = false; 15 | bool generateBcl = false; 16 | bool generateBuild = false; 17 | bool time = false; 18 | 19 | var options = new OptionSet() 20 | { 21 | { "r", v => run = v != null }, 22 | { "bcl", v => generateBcl = v != null }, 23 | { "build", v => generateBuild = v != null }, 24 | { "t", v => time = v != null } 25 | }; 26 | 27 | var path = Directory.GetCurrentDirectory(); 28 | var extra = options.Parse(args); 29 | if (extra.Count != 0) 30 | path = extra[0]; 31 | 32 | #if DEBUG 33 | path = @"C:\Users\Chris\Source\TaffyScript\WhereIsEveryone"; 34 | #endif 35 | 36 | if (generateBuild) 37 | { 38 | var build = new BuildConfig(); 39 | build.References.Add("TaffyScript.BCL.dll"); 40 | build.Save(path); 41 | return; 42 | } 43 | 44 | Console.WriteLine("Compile Start..."); 45 | Stopwatch sw = null; 46 | if (time) 47 | { 48 | sw = new Stopwatch(); 49 | sw.Start(); 50 | } 51 | 52 | var logger = new ErrorLogger(); 53 | 54 | var compiler = new MsilWeakCompiler(logger); 55 | CompilerResult result; 56 | 57 | if (!generateBcl) 58 | { 59 | result = compiler.CompileProject(path); 60 | } 61 | else 62 | result = compiler.CompileCode(BaseClassLibraryGenerator.Generate(), new BuildConfig() { Mode = CompileMode.Release, Output = Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location), "Libraries", "TaffyScript.BCL") }); 63 | 64 | if (result.Errors.Count == 0) 65 | { 66 | if(result.Warnings.Count > 0) 67 | { 68 | Console.WriteLine("Warnings:\n"); 69 | foreach (var warning in result.Warnings) 70 | Console.WriteLine(warning); 71 | Console.WriteLine('\n'); 72 | } 73 | 74 | Console.WriteLine("Compile succeeded..."); 75 | if(time) 76 | { 77 | sw.Stop(); 78 | Console.WriteLine($"Compile time: {sw.ElapsedMilliseconds} ms"); 79 | } 80 | Console.WriteLine($"Output: {result.PathToAssembly}"); 81 | if (run && result.PathToAssembly.EndsWith(".exe")) 82 | { 83 | Console.WriteLine("Running...\n"); 84 | RunOutput(result.PathToAssembly); 85 | } 86 | } 87 | else 88 | { 89 | Console.WriteLine("Compile failed..."); 90 | Console.WriteLine("Errors: \n"); 91 | foreach (var error in result.Errors) 92 | Console.WriteLine(error); 93 | } 94 | } 95 | 96 | private static void RunOutput(string location) 97 | { 98 | var psi = new ProcessStartInfo(location) 99 | { 100 | RedirectStandardError = true, 101 | RedirectStandardInput = true, 102 | RedirectStandardOutput = true, 103 | CreateNoWindow = true, 104 | UseShellExecute = false, 105 | }; 106 | 107 | using (var process = new Process()) 108 | { 109 | process.StartInfo = psi; 110 | process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data); 111 | process.ErrorDataReceived += (s, e) => Console.WriteLine(e.Data); 112 | process.Start(); 113 | process.BeginOutputReadLine(); 114 | process.BeginErrorReadLine(); 115 | process.WaitForExit(); 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /TaffyScript.Compiler/SymbolResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using TaffyScript.Compiler.FrontEnd; 7 | using TaffyScript.Compiler.Syntax; 8 | 9 | namespace TaffyScript.Compiler 10 | { 11 | public class SymbolResolver 12 | { 13 | SymbolTable _table; 14 | IErrorLogger _logger; 15 | 16 | public SymbolResolver(SymbolTable table, IErrorLogger logger) 17 | { 18 | _table = table; 19 | _logger = logger; 20 | } 21 | 22 | public string GetAssetNamespace(ISymbol symbol) 23 | { 24 | var sb = new StringBuilder(); 25 | var parent = symbol.Parent; 26 | while(parent != null && parent.Type == SymbolType.Namespace) 27 | { 28 | sb.Insert(0, parent.Name + "."); 29 | parent = parent.Parent; 30 | } 31 | return sb.ToString().TrimEnd(); 32 | } 33 | 34 | public string GetAssetFullName(ISymbol symbol) 35 | { 36 | var sb = new StringBuilder(symbol.Name); 37 | symbol = symbol.Parent; 38 | while(symbol != null && symbol.Type == SymbolType.Namespace) 39 | { 40 | sb.Insert(0, symbol.Name + "."); 41 | symbol = symbol.Parent; 42 | } 43 | return sb.ToString().TrimStart('.'); 44 | } 45 | 46 | public bool TryResolveNamespace(MemberAccessNode node, out ISyntaxElement resolved, out SymbolNode namespaceNode) 47 | { 48 | if (node.Left is ISyntaxToken token && _table.Defined(token.Name, out var symbol) && symbol.Type == SymbolType.Namespace) 49 | { 50 | namespaceNode = (SymbolNode)symbol; 51 | resolved = node.Right; 52 | return true; 53 | } 54 | else if (node.Left is MemberAccessNode) 55 | { 56 | var ns = new Stack(); 57 | resolved = node.Right; 58 | var start = node; 59 | while (node.Left is MemberAccessNode member) 60 | { 61 | node = member; 62 | if (node.Right is ISyntaxToken id) 63 | ns.Push(id); 64 | else 65 | { 66 | namespaceNode = default(SymbolNode); 67 | return false; 68 | } 69 | } 70 | 71 | if (node.Left is ISyntaxToken left) 72 | ns.Push(left); 73 | else 74 | { 75 | namespaceNode = default(SymbolNode); 76 | return false; 77 | } 78 | 79 | var sb = new System.Text.StringBuilder(); 80 | var iterations = 0; 81 | while (ns.Count > 0) 82 | { 83 | var top = ns.Pop(); 84 | sb.Append(top.Name); 85 | sb.Append("."); 86 | if (_table.Defined(top.Name, out symbol) && symbol.Type == SymbolType.Namespace) 87 | { 88 | _table.Enter(top.Name); 89 | iterations++; 90 | } 91 | else 92 | { 93 | namespaceNode = default(SymbolNode); 94 | _table.Exit(iterations); 95 | return false; 96 | } 97 | } 98 | namespaceNode = _table.Current; 99 | _table.Exit(iterations); 100 | return true; 101 | } 102 | resolved = default(ISyntaxElement); 103 | namespaceNode = default(SymbolNode); 104 | return false; 105 | } 106 | 107 | public bool TryResolveType(ISyntaxElement typeElement, out ISymbol typeSymbol) 108 | { 109 | if(((typeElement is MemberAccessNode memberAccess && 110 | TryResolveNamespace(memberAccess, out var token, out var ns) && 111 | ns.Children.TryGetValue(((ISyntaxToken)token).Name, out typeSymbol)) || 112 | (_table.Defined(((ISyntaxToken)typeElement).Name, out typeSymbol)))) 113 | { 114 | return true; 115 | } 116 | 117 | typeSymbol = default(ISymbol); 118 | return false; 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Samples/TestSuite/UnitTestLib/unit_test.tfs: -------------------------------------------------------------------------------- 1 | //This project is based off of the GaMaTas project for GameMaker Studio. 2 | //To find more information, you can view the project here: 3 | //https://github.com/gm-core/gamatas 4 | 5 | namespace UnitTest { 6 | object obj_unit_test { 7 | script create(test_suite_name) { 8 | if(argument_count < 2) 9 | show_error("You must provide at least the test suite name and one test.", true); 10 | 11 | test_number = 0; 12 | tests_failed = false; 13 | test_suite = test_suite_name; 14 | test_description = ""; 15 | tests = new ds_list(); 16 | for(var i = 1; i < argument_count; i++) { 17 | tests.add(argument[i]); 18 | } 19 | } 20 | 21 | script run_tests() { 22 | var count = tests.count; 23 | for(var i = 0; i < count; i++) { 24 | global._unit_test = self; 25 | test_description = ""; 26 | tests[i](); 27 | print(string(test_description) + " tests have passed."); 28 | } 29 | if(tests_failed) 30 | show_error("Not all tests passed. See output for more info.", true); 31 | else 32 | print("All tests have passed - " + test_suite); 33 | } 34 | } 35 | 36 | script test_it { 37 | global._unit_test.test_description = argument0; 38 | } 39 | 40 | script assert { 41 | if(argument_count == 1) 42 | assert_is_true(argument0); 43 | else 44 | assert_is_true(argument0, argument1); 45 | } 46 | 47 | script assert_equal { 48 | global._unit_test.test_number++; 49 | if(argument0 != argument1) { 50 | var msg; 51 | if(argument_count > 2) 52 | msg = argument2; 53 | else { 54 | msg = scr_ut_create_assert_error(string(argument0) + " is not " + string(argument1)); 55 | } 56 | 57 | test_fail(msg); 58 | } 59 | } 60 | 61 | script assert_not_equal { 62 | global._unit_test.test_number++; 63 | if(argument0 == argument1) { 64 | var msg; 65 | if(argument_count > 2) 66 | msg = argument2; 67 | else 68 | msg = scr_ut_create_assert_error(string(argument0) + " is " + string(argument1)); 69 | 70 | test_fail(msg); 71 | } 72 | } 73 | 74 | script assert_exists { 75 | global._unit_test.test_number++; 76 | if(!instance_exists(argument0)){ 77 | var msg; 78 | if(argument_count > 1) 79 | msg = argument1; 80 | else 81 | msg = scr_ut_create_assert_error(string(argument0) + " has no instances"); 82 | 83 | test_fail(msg); 84 | } 85 | } 86 | 87 | script assert_does_not_exist { 88 | global._unit_test.test_number++; 89 | if(instance_exists(argument0)){ 90 | var msg; 91 | if(argument_count > 1) 92 | msg = argument1; 93 | else 94 | msg = scr_ut_create_assert_error(string(argument0) + " should not exist"); 95 | 96 | test_fail(msg); 97 | } 98 | } 99 | 100 | script assert_is_true { 101 | if(argument_count > 1) 102 | assert_equal(argument0, true, argument1); 103 | else 104 | assert_equal(argument0, true); 105 | } 106 | 107 | script assert_is_false { 108 | if(argument_count > 1) 109 | assert_equal(argument0, false, argument1); 110 | else 111 | assert_equal(argument0, false); 112 | } 113 | 114 | script assert_is_undefined { 115 | global._unit_test.test_number++; 116 | if(!is_undefined(argument0)) { 117 | var msg; 118 | if(argument_count > 1) 119 | msg = argument1; 120 | else 121 | msg = scr_ut_create_assert_error(string(argument0) + " is not undefined"); 122 | } 123 | } 124 | 125 | script scr_ut_create_assert_error { 126 | return "ASSERT ERROR - " + string(argument0) + " - ASSERT #" + string(global._unit_test.test_number); 127 | } 128 | 129 | script test_fail { 130 | var msg = argument0; 131 | print(msg); 132 | print(global._unit_test.test_description); 133 | print("In suite " + global._unit_test.test_suite); 134 | 135 | global._unit_test.tests_failed = true; 136 | } 137 | } -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/map.tfs: -------------------------------------------------------------------------------- 1 | using UnitTest; 2 | using TaffyScript.Collections; 3 | 4 | namespace LanguageTests { 5 | script run_map_tests() { 6 | var tests = new obj_unit_test("Map Tests", 7 | map_create, 8 | map_add_new, 9 | map_add_duplicate, 10 | map_clear, 11 | map_remove_true, 12 | map_remove_false, 13 | map_contains_key_true, 14 | map_contains_key_false, 15 | map_copy, 16 | map_keys_some, 17 | map_keys_none, 18 | map_get_script, 19 | map_get_access, 20 | map_set_script, 21 | map_set_access); 22 | 23 | tests.run_tests(); 24 | } 25 | 26 | script map_create() { 27 | test_it("var m = new Map()"); 28 | var map = new Map(); 29 | assert_equal(object_get_name(map), "Map"); 30 | } 31 | 32 | script map_add_new() { 33 | test_it("map.add(key (uniq), val)"); 34 | var map = new Map(); 35 | assert(map.add("key", "val")); 36 | assert_equal(map.count, 1); 37 | } 38 | 39 | script map_add_duplicate() { 40 | test_it("map.add(key (dup), val)"); 41 | var map = new Map(); 42 | assert(map.add("key", 4)); 43 | assert_is_false(map.add("key", "val")); 44 | assert_equal(map.count, 1); 45 | } 46 | 47 | script map_clear() { 48 | test_it("map.clear()"); 49 | var map = new Map(); 50 | map.add(0, 2); 51 | map.add("moo", "cow"); 52 | assert_equal(map.count, 2); 53 | map.clear(); 54 | assert_equal(map.count, 0); 55 | } 56 | 57 | script map_remove_true() { 58 | test_it("map.remove(key) == true"); 59 | var map = new Map(); 60 | map.add(0, 2); 61 | map.add("moo", "cow"); 62 | assert_equal(map.count, 2); 63 | assert(map.remove(0)); 64 | assert_equal(map.count, 1); 65 | } 66 | 67 | script map_remove_false() { 68 | test_it("map.remove(key) == false"); 69 | var map = new Map(); 70 | map.add(0, 2); 71 | map.add("moo", "cow"); 72 | assert_equal(map.count, 2); 73 | assert_is_false(map.remove(1)); 74 | assert_equal(map.count, 2); 75 | } 76 | 77 | script map_contains_key_true() { 78 | test_it("map.contains_key(key) == true"); 79 | var map = new Map(); 80 | map.add(0, 2); 81 | map.add("moo", "cow"); 82 | assert(map.contains_key("moo")); 83 | } 84 | 85 | script map_contains_key_false() { 86 | test_it("map.contains_key(key) == false"); 87 | var map = new Map(); 88 | map.add(0, 2); 89 | map.add("moo", "cow"); 90 | assert_is_false(map.contains_key("cow")); 91 | } 92 | 93 | script map_copy() { 94 | test_it("map.copy()"); 95 | var map = new Map(); 96 | map.add(0, 2); 97 | map.add("moo", "cow"); 98 | var copy = map.copy(); 99 | assert_equal(map.count, 2); 100 | assert_equal(map.count, copy.count); 101 | assert_is_false(map == copy); 102 | } 103 | 104 | script map_keys_some() { 105 | test_it("map.keys.length > 0"); 106 | var map = new Map(); 107 | map.add(0, 2); 108 | map.add("moo", "cow"); 109 | var keys = map.keys; 110 | assert_equal(array_length_1d(keys), 2); 111 | } 112 | 113 | script map_keys_none() { 114 | test_it("map.keys.length == 0"); 115 | var map = new Map(); 116 | var keys = map.keys; 117 | assert_equal(array_length_1d(keys), 0); 118 | } 119 | 120 | script map_get_script() { 121 | test_it("map.get(key)"); 122 | var map = new Map(); 123 | map.add("moo", "cow"); 124 | assert_equal(map.get("moo"), "cow"); 125 | } 126 | 127 | script map_get_access() { 128 | test_it("val = map[key]"); 129 | var map = new Map(); 130 | map.add("moo", "cow"); 131 | assert_equal(map["moo"], "cow"); 132 | } 133 | 134 | script map_set_script() { 135 | test_it("map.set(key, val)"); 136 | var map = new Map(); 137 | map.set("moo", "cow"); 138 | assert_equal(map["moo"], "cow"); 139 | } 140 | 141 | script map_set_access() { 142 | test_it("map[key] = val"); 143 | var map = new Map(); 144 | map["moo"] = "cow"; 145 | assert_equal(map["moo"], "cow"); 146 | } 147 | } -------------------------------------------------------------------------------- /Samples/TestSuite/Tests/struct.tfs: -------------------------------------------------------------------------------- 1 | // Structs aren't implemented yed; they may never be. 2 | // This file shows a potential implementation. 3 | // Currently it's excluded from the build. 4 | 5 | using UnitTest; 6 | 7 | namespace LanguageTests { 8 | struct point { 9 | x : int; 10 | y : int; 11 | } 12 | 13 | script point_create(x, y) { 14 | var p = new point(); 15 | p.x = x; 16 | p.y = y; 17 | 18 | return p; 19 | } 20 | 21 | struct linked_list_node { 22 | next; 23 | previous; 24 | value; 25 | } 26 | 27 | struct linked_list { 28 | head, 29 | tail, 30 | count 31 | } 32 | 33 | script linked_list_create() { 34 | var ll = new linked_list(); 35 | ll.head = null; 36 | ll.tail = null; 37 | ll.count = 0; 38 | return ll; 39 | } 40 | } 41 | 42 | namespace NotARealNamespace { 43 | 44 | //TaffyScript 45 | object obj_ts_class { 46 | script create(x, y) { 47 | self.x = x; 48 | self.y = y; 49 | } 50 | 51 | script say_hello(name) { 52 | print("hello " + string(name)); 53 | } 54 | } 55 | 56 | //C# 57 | public class obj_ts_class : ITsIntance { 58 | private static Dictionary _scripts; 59 | private Dictionary _vars; 60 | 61 | static obj_ts_class() { 62 | _scripts = new Dictionary() 63 | { 64 | { "say_hello", new TsDelegate("say_hello", say_hello) }, 65 | { "create", new TsDelegate("create", create) } 66 | } 67 | } 68 | 69 | public virtual string ObjectType => "obj_ts_class"; 70 | 71 | public virtual TsObject this[string memberName] 72 | { 73 | get => GetMember(memberName); 74 | set => _vars[memberName] = value; 75 | } 76 | 77 | public virtual obj_ts_class(params TsObject[] args) { 78 | create(this, args); 79 | } 80 | 81 | public virtual TsObject Call(stirng scriptName, params TsObject[] args) { 82 | if(TryGetDelegate(scriptName, out var del)) 83 | return del.Invoke(args); 84 | 85 | throw new MemberAccessException(); 86 | } 87 | 88 | public virtual bool TryGetDelegate(string scriptName, out TsDelegate del) { 89 | if(_vars.TryGetValue(scriptName, out var member)) 90 | { 91 | if(member.Type != VariableType.Delegate) { 92 | del = null; 93 | return false; 94 | } 95 | del = member.GetDelegateUnchecked(); 96 | return true; 97 | } 98 | if(_scripts.TryGetValue(scriptName, out del)) { 99 | del = new TsDelegate(del, this); 100 | _vars.Add(scriptName, del); 101 | return del; 102 | } 103 | del = null; 104 | return false; 105 | } 106 | 107 | public virtual TsObject GetMember(string memberName) { 108 | if(_vars.TryGetValue(memberName, out var member)) 109 | return member; 110 | if(TryGetDelegate(memberName, out var del)) 111 | return del; 112 | throw new MemberAccessException(); 113 | } 114 | 115 | public virtual void SetMember(string memberName, TsObject value) { 116 | _vars[memberName] = value; 117 | } 118 | 119 | /*public virtual bool MemberExists(string memberName) 120 | { 121 | if(_vars.ContainsKey(memberName) || _scripts.ContainsKey(memberName)) 122 | return true; 123 | 124 | return false; 125 | } 126 | 127 | public virtual IEnumerable GetMemberNames() 128 | { 129 | var set = new HashSet(_vars.Keys); 130 | set.UnionWith(_scripts.Keys); 131 | return set; 132 | } 133 | 134 | public virtual TsObject say_hello(params TsObject[] args) 135 | { 136 | Console.WriteLine("hello " + args[0].ToString()); 137 | } 138 | 139 | public virtual TsObject create(params TsObject[] args) 140 | { 141 | _vars["x"] = args[0]; 142 | _vars["y"] = args[1]; 143 | }*/ 144 | 145 | public static TsObject say_hello(ITsIntance target, params TsObject[] args) { 146 | Console.WriteLine("hello " + args[0].ToString()); 147 | } 148 | 149 | public static TsObject create(ITsIntance target, params TsObject[] args) { 150 | target["x"] = args[0]; 151 | target["y"] = args[1]; 152 | } 153 | 154 | internal static Dictionary Initialize() 155 | { 156 | // Must have been created in static method. 157 | return _scripts; 158 | } 159 | } 160 | } --------------------------------------------------------------------------------