Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eb8e522bf2 | |||
| 16b71ba6f4 | |||
| 9725f3c6a3 | |||
| 8653a2663f | |||
| ab2cd5dc93 | |||
| 724804a78a | |||
| 77a128e0f7 | |||
| 5343e1054d | |||
| 3930ec0477 | |||
| 996744d7ec | |||
| c00b32017b | |||
| 457014d577 | |||
| be4cbf1ad6 |
+4
-3
@@ -1,6 +1,4 @@
|
|||||||
#Editor generated files
|
#Editor generated files
|
||||||
*.sln
|
|
||||||
*.vcproj
|
|
||||||
*.suo
|
*.suo
|
||||||
*.ncb
|
*.ncb
|
||||||
*.user
|
*.user
|
||||||
@@ -13,7 +11,9 @@ Out/
|
|||||||
release/
|
release/
|
||||||
debug/
|
debug/
|
||||||
out/
|
out/
|
||||||
|
bin/
|
||||||
.cache/
|
.cache/
|
||||||
|
.vs/
|
||||||
|
|
||||||
#Project generated files
|
#Project generated files
|
||||||
*.db
|
*.db
|
||||||
@@ -22,9 +22,10 @@ out/
|
|||||||
*.exe
|
*.exe
|
||||||
*.meta
|
*.meta
|
||||||
*.log
|
*.log
|
||||||
out
|
*.out
|
||||||
*.stackdump
|
*.stackdump
|
||||||
*.tb
|
*.tb
|
||||||
|
*.filters
|
||||||
|
|
||||||
#Shell files
|
#Shell files
|
||||||
*.bat
|
*.bat
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ Special thanks to http://craftinginterpreters.com/ for their fantastic book that
|
|||||||
|
|
||||||
For Windows(mingw32 & cygwin), Linux and MacOS, simply run `make` in the root directory.
|
For Windows(mingw32 & cygwin), Linux and MacOS, simply run `make` in the root directory.
|
||||||
|
|
||||||
Note: MacOS is not officially supported (no machines for testing), but we'll do our best!
|
For Windows(MSVC), Visual Studio project files are included.
|
||||||
|
|
||||||
|
Note: MacOS and Windows(MSVC) are not officially supported, but we'll do our best!
|
||||||
|
|
||||||
## Tools
|
## Tools
|
||||||
|
|
||||||
|
|||||||
+133
@@ -0,0 +1,133 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>17.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{97F823E5-3AB8-47EF-B142-C15DD7CADF76}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<IgnoreImportLibrary>false</IgnoreImportLibrary>
|
||||||
|
<OutDir>$(SolutionDir)out\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>Toy.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>$(SolutionDir)out\$(Configuration)</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalIncludeDirectories>C:\Users\kayne\Desktop\Toy\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="repl\lib_about.c" />
|
||||||
|
<ClCompile Include="repl\lib_compound.c" />
|
||||||
|
<ClCompile Include="repl\lib_runner.c" />
|
||||||
|
<ClCompile Include="repl\lib_standard.c" />
|
||||||
|
<ClCompile Include="repl\repl_main.c" />
|
||||||
|
<ClCompile Include="repl\repl_tools.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="repl\lib_about.h" />
|
||||||
|
<ClInclude Include="repl\lib_compound.h" />
|
||||||
|
<ClInclude Include="repl\lib_runner.h" />
|
||||||
|
<ClInclude Include="repl\lib_standard.h" />
|
||||||
|
<ClInclude Include="repl\repl_tools.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
+148
@@ -0,0 +1,148 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>17.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{26360002-CC2A-469A-9B28-BA0C1AF41657}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<OutDir>$(SolutionDir)out\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TOY_EXPORTS;TOY_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;TOY_EXPORTS;TOY_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>TOY_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="source\toy_ast_node.c" />
|
||||||
|
<ClCompile Include="source\toy_builtin.c" />
|
||||||
|
<ClCompile Include="source\toy_common.c" />
|
||||||
|
<ClCompile Include="source\toy_compiler.c" />
|
||||||
|
<ClCompile Include="source\toy_interpreter.c" />
|
||||||
|
<ClCompile Include="source\toy_keyword_types.c" />
|
||||||
|
<ClCompile Include="source\toy_lexer.c" />
|
||||||
|
<ClCompile Include="source\toy_literal.c" />
|
||||||
|
<ClCompile Include="source\toy_literal_array.c" />
|
||||||
|
<ClCompile Include="source\toy_literal_dictionary.c" />
|
||||||
|
<ClCompile Include="source\toy_memory.c" />
|
||||||
|
<ClCompile Include="source\toy_parser.c" />
|
||||||
|
<ClCompile Include="source\toy_refstring.c" />
|
||||||
|
<ClCompile Include="source\toy_scope.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="source\toy_ast_node.h" />
|
||||||
|
<ClInclude Include="source\toy_builtin.h" />
|
||||||
|
<ClInclude Include="source\toy_common.h" />
|
||||||
|
<ClInclude Include="source\toy_compiler.h" />
|
||||||
|
<ClInclude Include="source\toy_console_colors.h" />
|
||||||
|
<ClInclude Include="source\toy_interpreter.h" />
|
||||||
|
<ClInclude Include="source\toy_keyword_types.h" />
|
||||||
|
<ClInclude Include="source\toy_lexer.h" />
|
||||||
|
<ClInclude Include="source\toy_literal.h" />
|
||||||
|
<ClInclude Include="source\toy_literal_array.h" />
|
||||||
|
<ClInclude Include="source\toy_literal_dictionary.h" />
|
||||||
|
<ClInclude Include="source\toy_memory.h" />
|
||||||
|
<ClInclude Include="source\toy_opcodes.h" />
|
||||||
|
<ClInclude Include="source\toy_parser.h" />
|
||||||
|
<ClInclude Include="source\toy_refstring.h" />
|
||||||
|
<ClInclude Include="source\toy_scope.h" />
|
||||||
|
<ClInclude Include="source\toy_token_types.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.4.33213.308
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Toy", "Toy.vcxproj", "{26360002-CC2A-469A-9B28-BA0C1AF41657}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Repl", "Repl.vcxproj", "{97F823E5-3AB8-47EF-B142-C15DD7CADF76}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{26360002-CC2A-469A-9B28-BA0C1AF41657} = {26360002-CC2A-469A-9B28-BA0C1AF41657}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Release|x64.Build.0 = Release|x64
|
||||||
|
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{26360002-CC2A-469A-9B28-BA0C1AF41657}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Release|x64.Build.0 = Release|x64
|
||||||
|
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{97F823E5-3AB8-47EF-B142-C15DD7CADF76}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {7089F1AD-8EC0-4F27-AFD1-5FD43D91AABC}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
@@ -10,10 +10,10 @@ all: $(TOY_OUTDIR) repl
|
|||||||
|
|
||||||
#repl builds
|
#repl builds
|
||||||
repl: $(TOY_OUTDIR) library
|
repl: $(TOY_OUTDIR) library
|
||||||
$(MAKE) -C repl
|
$(MAKE) -j8 -C repl
|
||||||
|
|
||||||
repl-static: $(TOY_OUTDIR) static
|
repl-static: $(TOY_OUTDIR) static
|
||||||
$(MAKE) -C repl
|
$(MAKE) -j8 -C repl
|
||||||
|
|
||||||
repl-release: clean $(TOY_OUTDIR) library-release
|
repl-release: clean $(TOY_OUTDIR) library-release
|
||||||
$(MAKE) -C repl release
|
$(MAKE) -C repl release
|
||||||
|
|||||||
-1468
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
|
|
||||||
int Toy_hookCompound(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
|
||||||
|
|
||||||
+5
-5
@@ -44,7 +44,7 @@ static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu
|
|||||||
|
|
||||||
//use raw types - easier
|
//use raw types - easier
|
||||||
const char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral));
|
const char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral));
|
||||||
int filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral));
|
size_t filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral));
|
||||||
|
|
||||||
//load and compile the bytecode
|
//load and compile the bytecode
|
||||||
size_t fileSize = 0;
|
size_t fileSize = 0;
|
||||||
@@ -138,7 +138,7 @@ static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArr
|
|||||||
|
|
||||||
//get the final real file path (concat) TODO: move this concat to refstring library
|
//get the final real file path (concat) TODO: move this concat to refstring library
|
||||||
Toy_RefString* realDrive = Toy_copyRefString(TOY_AS_STRING(realDriveLiteral));
|
Toy_RefString* realDrive = Toy_copyRefString(TOY_AS_STRING(realDriveLiteral));
|
||||||
int realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path);
|
size_t realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path);
|
||||||
|
|
||||||
char* filePath = TOY_ALLOCATE(char, realLength + 1); //+1 for null
|
char* filePath = TOY_ALLOCATE(char, realLength + 1); //+1 for null
|
||||||
snprintf(filePath, realLength, "%s%s", Toy_toCString(realDrive), Toy_toCString(path));
|
snprintf(filePath, realLength, "%s%s", Toy_toCString(realDrive), Toy_toCString(path));
|
||||||
@@ -159,7 +159,7 @@ static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArr
|
|||||||
}
|
}
|
||||||
|
|
||||||
//check for break-out attempts
|
//check for break-out attempts
|
||||||
for (int i = 0; i < realLength - 1; i++) {
|
for (size_t i = 0; i < realLength - 1; i++) {
|
||||||
if (filePath[i] == '.' && filePath[i + 1] == '.') {
|
if (filePath[i] == '.' && filePath[i + 1] == '.') {
|
||||||
interpreter->errorOutput("Parent directory access not allowed\n");
|
interpreter->errorOutput("Parent directory access not allowed\n");
|
||||||
TOY_FREE_ARRAY(char, filePath, realLength);
|
TOY_FREE_ARRAY(char, filePath, realLength);
|
||||||
@@ -617,7 +617,7 @@ Toy_Literal Toy_getFilePathLiteral(Toy_Interpreter* interpreter, Toy_Literal* dr
|
|||||||
|
|
||||||
//get the final real file path (concat) TODO: move this concat to refstring library
|
//get the final real file path (concat) TODO: move this concat to refstring library
|
||||||
Toy_RefString* realDrive = Toy_copyRefString(TOY_AS_STRING(realDriveLiteral));
|
Toy_RefString* realDrive = Toy_copyRefString(TOY_AS_STRING(realDriveLiteral));
|
||||||
int realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path);
|
size_t realLength = Toy_lengthRefString(realDrive) + Toy_lengthRefString(path);
|
||||||
|
|
||||||
char* filePath = TOY_ALLOCATE(char, realLength + 1); //+1 for null
|
char* filePath = TOY_ALLOCATE(char, realLength + 1); //+1 for null
|
||||||
snprintf(filePath, realLength, "%s%s", Toy_toCString(realDrive), Toy_toCString(path));
|
snprintf(filePath, realLength, "%s%s", Toy_toCString(realDrive), Toy_toCString(path));
|
||||||
@@ -630,7 +630,7 @@ Toy_Literal Toy_getFilePathLiteral(Toy_Interpreter* interpreter, Toy_Literal* dr
|
|||||||
Toy_deleteRefString(drivePath);
|
Toy_deleteRefString(drivePath);
|
||||||
|
|
||||||
//check for break-out attempts
|
//check for break-out attempts
|
||||||
for (int i = 0; i < realLength - 1; i++) {
|
for (size_t i = 0; i < realLength - 1; i++) {
|
||||||
if (filePath[i] == '.' && filePath[i + 1] == '.') {
|
if (filePath[i] == '.' && filePath[i + 1] == '.') {
|
||||||
interpreter->errorOutput("Parent directory access not allowed\n");
|
interpreter->errorOutput("Parent directory access not allowed\n");
|
||||||
TOY_FREE_ARRAY(char, filePath, realLength + 1);
|
TOY_FREE_ARRAY(char, filePath, realLength + 1);
|
||||||
|
|||||||
+1538
-2
File diff suppressed because it is too large
Load Diff
@@ -1,411 +0,0 @@
|
|||||||
#include "lib_timer.h"
|
|
||||||
|
|
||||||
#include "toy_memory.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
//GOD DAMN IT: https://stackoverflow.com/questions/15846762/timeval-subtract-explanation
|
|
||||||
static int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) {
|
|
||||||
//normallize
|
|
||||||
if (x->tv_usec > 999999) {
|
|
||||||
x->tv_sec += x->tv_usec / 1000000;
|
|
||||||
x->tv_usec %= 1000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y->tv_usec > 999999) {
|
|
||||||
y->tv_sec += y->tv_usec / 1000000;
|
|
||||||
y->tv_usec %= 1000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
//calc
|
|
||||||
result->tv_sec = x->tv_sec - y->tv_sec;
|
|
||||||
|
|
||||||
if ((result->tv_usec = x->tv_usec - y->tv_usec) < 0) {
|
|
||||||
if (result->tv_sec != 0) { //only works far from 0
|
|
||||||
result->tv_usec += 1000000;
|
|
||||||
result->tv_sec--; // borrow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result->tv_sec < 0 || (result->tv_sec == 0 && result->tv_usec < 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//god damn it
|
|
||||||
static struct timeval* diff(struct timeval* lhs, struct timeval* rhs) {
|
|
||||||
struct timeval* d = TOY_ALLOCATE(struct timeval, 1);
|
|
||||||
|
|
||||||
//I gave up, copied from SO
|
|
||||||
timeval_subtract(d, rhs, lhs);
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
//callbacks
|
|
||||||
static int nativeStartTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 0) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to startTimer\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the timeinfo from C
|
|
||||||
struct timeval* timeinfo = TOY_ALLOCATE(struct timeval, 1);
|
|
||||||
gettimeofday(timeinfo, NULL);
|
|
||||||
|
|
||||||
//wrap in an opaque literal for Toy
|
|
||||||
Toy_Literal timeLiteral = TOY_TO_OPAQUE_LITERAL(timeinfo, -1);
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, timeLiteral);
|
|
||||||
|
|
||||||
Toy_freeLiteral(timeLiteral);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeStopTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to _stopTimer\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the timeinfo from C
|
|
||||||
struct timeval timerStop;
|
|
||||||
gettimeofday(&timerStop, NULL);
|
|
||||||
|
|
||||||
//unwrap the opaque literal
|
|
||||||
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal timeLiteralIdn = timeLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
|
|
||||||
Toy_freeLiteral(timeLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TOY_IS_OPAQUE(timeLiteral)) {
|
|
||||||
interpreter->errorOutput("Incorrect argument type passed to _stopTimer\n");
|
|
||||||
Toy_freeLiteral(timeLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct timeval* timerStart = TOY_AS_OPAQUE(timeLiteral);
|
|
||||||
|
|
||||||
//determine the difference, and wrap it
|
|
||||||
struct timeval* d = diff(timerStart, &timerStop);
|
|
||||||
Toy_Literal diffLiteral = TOY_TO_OPAQUE_LITERAL(d, -1);
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, diffLiteral);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(timeLiteral);
|
|
||||||
Toy_freeLiteral(diffLiteral);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeCreateTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 2) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to createTimer\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the args
|
|
||||||
Toy_Literal microsecondLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
Toy_Literal secondLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal secondLiteralIdn = secondLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(secondLiteral) && Toy_parseIdentifierToValue(interpreter, &secondLiteral)) {
|
|
||||||
Toy_freeLiteral(secondLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal microsecondLiteralIdn = microsecondLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(microsecondLiteral) && Toy_parseIdentifierToValue(interpreter, µsecondLiteral)) {
|
|
||||||
Toy_freeLiteral(microsecondLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TOY_IS_INTEGER(secondLiteral) || !TOY_IS_INTEGER(microsecondLiteral)) {
|
|
||||||
interpreter->errorOutput("Incorrect argument type passed to createTimer\n");
|
|
||||||
Toy_freeLiteral(secondLiteral);
|
|
||||||
Toy_freeLiteral(microsecondLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_AS_INTEGER(microsecondLiteral) <= -1000 * 1000 || TOY_AS_INTEGER(microsecondLiteral) >= 1000 * 1000 || (TOY_AS_INTEGER(secondLiteral) != 0 && TOY_AS_INTEGER(microsecondLiteral) < 0) ) {
|
|
||||||
interpreter->errorOutput("Microseconds out of range in createTimer\n");
|
|
||||||
Toy_freeLiteral(secondLiteral);
|
|
||||||
Toy_freeLiteral(microsecondLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the timeinfo from toy
|
|
||||||
struct timeval* timeinfo = TOY_ALLOCATE(struct timeval, 1);
|
|
||||||
timeinfo->tv_sec = TOY_AS_INTEGER(secondLiteral);
|
|
||||||
timeinfo->tv_usec = TOY_AS_INTEGER(microsecondLiteral);
|
|
||||||
|
|
||||||
//wrap in an opaque literal for Toy
|
|
||||||
Toy_Literal timeLiteral = TOY_TO_OPAQUE_LITERAL(timeinfo, -1);
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, timeLiteral);
|
|
||||||
|
|
||||||
Toy_freeLiteral(timeLiteral);
|
|
||||||
Toy_freeLiteral(secondLiteral);
|
|
||||||
Toy_freeLiteral(microsecondLiteral);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeGetTimerSeconds(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to _getTimerSeconds\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//unwrap the opaque literal
|
|
||||||
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal timeLiteralIdn = timeLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
|
|
||||||
Toy_freeLiteral(timeLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TOY_IS_OPAQUE(timeLiteral)) {
|
|
||||||
interpreter->errorOutput("Incorrect argument type passed to _getTimerSeconds\n");
|
|
||||||
Toy_freeLiteral(timeLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct timeval* timer = TOY_AS_OPAQUE(timeLiteral);
|
|
||||||
|
|
||||||
//create the result literal
|
|
||||||
Toy_Literal result = TOY_TO_INTEGER_LITERAL(timer->tv_sec);
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(timeLiteral);
|
|
||||||
Toy_freeLiteral(result);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeGetTimerMicroseconds(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to _getTimerMicroseconds\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//unwrap the opaque literal
|
|
||||||
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal timeLiteralIdn = timeLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
|
|
||||||
Toy_freeLiteral(timeLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TOY_IS_OPAQUE(timeLiteral)) {
|
|
||||||
interpreter->errorOutput("Incorrect argument type passed to _getTimerMicroseconds\n");
|
|
||||||
Toy_freeLiteral(timeLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct timeval* timer = TOY_AS_OPAQUE(timeLiteral);
|
|
||||||
|
|
||||||
//create the result literal
|
|
||||||
Toy_Literal result = TOY_TO_INTEGER_LITERAL(timer->tv_usec);
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(timeLiteral);
|
|
||||||
Toy_freeLiteral(result);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeCompareTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 2) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to _compareTimer\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//unwrap the opaque literals
|
|
||||||
Toy_Literal rhsLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
Toy_Literal lhsLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal lhsLiteralIdn = lhsLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(lhsLiteral) && Toy_parseIdentifierToValue(interpreter, &lhsLiteral)) {
|
|
||||||
Toy_freeLiteral(lhsLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal rhsLiteralIdn = rhsLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(rhsLiteral) && Toy_parseIdentifierToValue(interpreter, &rhsLiteral)) {
|
|
||||||
Toy_freeLiteral(rhsLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TOY_IS_OPAQUE(lhsLiteral) || !TOY_IS_OPAQUE(rhsLiteral)) {
|
|
||||||
interpreter->errorOutput("Incorrect argument type passed to _compareTimer\n");
|
|
||||||
Toy_freeLiteral(lhsLiteral);
|
|
||||||
Toy_freeLiteral(rhsLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct timeval* lhsTimer = TOY_AS_OPAQUE(lhsLiteral);
|
|
||||||
struct timeval* rhsTimer = TOY_AS_OPAQUE(rhsLiteral);
|
|
||||||
|
|
||||||
//determine the difference, and wrap it
|
|
||||||
struct timeval* d = diff(lhsTimer, rhsTimer);
|
|
||||||
Toy_Literal diffLiteral = TOY_TO_OPAQUE_LITERAL(d, -1);
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, diffLiteral);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(lhsLiteral);
|
|
||||||
Toy_freeLiteral(rhsLiteral);
|
|
||||||
Toy_freeLiteral(diffLiteral);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeTimerToString(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to _timerToString\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//unwrap in an opaque literal
|
|
||||||
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal timeLiteralIdn = timeLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
|
|
||||||
Toy_freeLiteral(timeLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TOY_IS_OPAQUE(timeLiteral)) {
|
|
||||||
interpreter->errorOutput("Incorrect argument type passed to _timerToString\n");
|
|
||||||
Toy_freeLiteral(timeLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct timeval* timer = TOY_AS_OPAQUE(timeLiteral);
|
|
||||||
|
|
||||||
//create the string literal
|
|
||||||
Toy_Literal resultLiteral = TOY_TO_NULL_LITERAL;
|
|
||||||
if (timer->tv_sec == 0 && timer->tv_usec < 0) { //special case, for when the negative sign is encoded in the usec
|
|
||||||
char buffer[128];
|
|
||||||
snprintf(buffer, 128, "-%ld.%06ld", timer->tv_sec, -timer->tv_usec);
|
|
||||||
resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, strlen(buffer)));
|
|
||||||
}
|
|
||||||
else { //normal case
|
|
||||||
char buffer[128];
|
|
||||||
snprintf(buffer, 128, "%ld.%06ld", timer->tv_sec, timer->tv_usec);
|
|
||||||
resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, strlen(buffer)));
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(timeLiteral);
|
|
||||||
Toy_freeLiteral(resultLiteral);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeDestroyTimer(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to _destroyTimer\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//unwrap in an opaque literal
|
|
||||||
Toy_Literal timeLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal timeLiteralIdn = timeLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(timeLiteral) && Toy_parseIdentifierToValue(interpreter, &timeLiteral)) {
|
|
||||||
Toy_freeLiteral(timeLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TOY_IS_OPAQUE(timeLiteral)) {
|
|
||||||
interpreter->errorOutput("Incorrect argument type passed to _destroyTimer\n");
|
|
||||||
Toy_freeLiteral(timeLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct timeval* timer = TOY_AS_OPAQUE(timeLiteral);
|
|
||||||
|
|
||||||
TOY_FREE(struct timeval, timer);
|
|
||||||
|
|
||||||
Toy_freeLiteral(timeLiteral);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//call the hook
|
|
||||||
typedef struct Natives {
|
|
||||||
char* name;
|
|
||||||
Toy_NativeFn fn;
|
|
||||||
} Natives;
|
|
||||||
|
|
||||||
int Toy_hookTimer(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
|
||||||
//build the natives list
|
|
||||||
Natives natives[] = {
|
|
||||||
{"startTimer", nativeStartTimer},
|
|
||||||
{"_stopTimer", nativeStopTimer},
|
|
||||||
{"createTimer", nativeCreateTimer},
|
|
||||||
{"_getTimerSeconds", nativeGetTimerSeconds},
|
|
||||||
{"_getTimerMicroseconds", nativeGetTimerMicroseconds},
|
|
||||||
{"_compareTimer", nativeCompareTimer},
|
|
||||||
{"_timerToString", nativeTimerToString},
|
|
||||||
{"_destroyTimer", nativeDestroyTimer},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
//store the library in an aliased dictionary
|
|
||||||
if (!TOY_IS_NULL(alias)) {
|
|
||||||
//make sure the name isn't taken
|
|
||||||
if (Toy_isDelcaredScopeVariable(interpreter->scope, alias)) {
|
|
||||||
interpreter->errorOutput("Can't override an existing variable\n");
|
|
||||||
Toy_freeLiteral(alias);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//create the dictionary to load up with functions
|
|
||||||
Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
|
||||||
Toy_initLiteralDictionary(dictionary);
|
|
||||||
|
|
||||||
//load the dict with functions
|
|
||||||
for (int i = 0; natives[i].name; i++) {
|
|
||||||
Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
|
|
||||||
Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn);
|
|
||||||
|
|
||||||
Toy_setLiteralDictionary(dictionary, name, func);
|
|
||||||
|
|
||||||
Toy_freeLiteral(name);
|
|
||||||
Toy_freeLiteral(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
//build the type
|
|
||||||
Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true);
|
|
||||||
Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
|
|
||||||
Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true);
|
|
||||||
TOY_TYPE_PUSH_SUBTYPE(&type, strType);
|
|
||||||
TOY_TYPE_PUSH_SUBTYPE(&type, fnType);
|
|
||||||
|
|
||||||
//set scope
|
|
||||||
Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary);
|
|
||||||
Toy_declareScopeVariable(interpreter->scope, alias, type);
|
|
||||||
Toy_setScopeVariable(interpreter->scope, alias, dict, false);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(dict);
|
|
||||||
Toy_freeLiteral(type);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//default
|
|
||||||
for (int i = 0; natives[i].name; i++) {
|
|
||||||
Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
|
|
||||||
int Toy_hookTimer(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
|
||||||
|
|
||||||
+63
-14
@@ -1,8 +1,6 @@
|
|||||||
#include "repl_tools.h"
|
#include "repl_tools.h"
|
||||||
#include "lib_about.h"
|
#include "lib_about.h"
|
||||||
#include "lib_compound.h"
|
|
||||||
#include "lib_standard.h"
|
#include "lib_standard.h"
|
||||||
#include "lib_timer.h"
|
|
||||||
#include "lib_runner.h"
|
#include "lib_runner.h"
|
||||||
|
|
||||||
#include "toy_console_colors.h"
|
#include "toy_console_colors.h"
|
||||||
@@ -16,31 +14,31 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void repl() {
|
#define INPUT_BUFFER_SIZE 2048
|
||||||
|
|
||||||
|
void repl(const char* initialInput) {
|
||||||
//repl does it's own thing for now
|
//repl does it's own thing for now
|
||||||
bool error = false;
|
bool error = false;
|
||||||
|
|
||||||
const int size = 2048;
|
char input[INPUT_BUFFER_SIZE];
|
||||||
char input[size];
|
memset(input, 0, INPUT_BUFFER_SIZE);
|
||||||
memset(input, 0, size);
|
|
||||||
|
|
||||||
Toy_Interpreter interpreter; //persist the interpreter for the scopes
|
Toy_Interpreter interpreter; //persist the interpreter for the scopes
|
||||||
Toy_initInterpreter(&interpreter);
|
Toy_initInterpreter(&interpreter);
|
||||||
|
|
||||||
//inject the libs
|
//inject the libs
|
||||||
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
||||||
Toy_injectNativeHook(&interpreter, "compound", Toy_hookCompound);
|
|
||||||
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
||||||
Toy_injectNativeHook(&interpreter, "timer", Toy_hookTimer);
|
|
||||||
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
printf("> ");
|
if (!initialInput) {
|
||||||
|
|
||||||
//handle EOF for exits
|
//handle EOF for exits
|
||||||
if (!fgets(input, size, stdin)) {
|
printf("> ");
|
||||||
|
if (!fgets(input, INPUT_BUFFER_SIZE, stdin)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//escape the repl (length of 5 to accomodate the newline)
|
//escape the repl (length of 5 to accomodate the newline)
|
||||||
if (strlen(input) == 5 && (!strncmp(input, "exit", 4) || !strncmp(input, "quit", 4))) {
|
if (strlen(input) == 5 && (!strncmp(input, "exit", 4) || !strncmp(input, "quit", 4))) {
|
||||||
@@ -52,8 +50,8 @@ void repl() {
|
|||||||
Toy_Parser parser;
|
Toy_Parser parser;
|
||||||
Toy_Compiler compiler;
|
Toy_Compiler compiler;
|
||||||
|
|
||||||
Toy_initLexer(&lexer, input);
|
Toy_initLexer(&lexer, initialInput ? initialInput : input);
|
||||||
Toy_private_setComments(&lexer, false); //BUGFIX: disable comments here
|
Toy_private_setComments(&lexer, initialInput != NULL); //BUGFIX: disable comments here
|
||||||
Toy_initParser(&parser, &lexer);
|
Toy_initParser(&parser, &lexer);
|
||||||
Toy_initCompiler(&compiler);
|
Toy_initCompiler(&compiler);
|
||||||
|
|
||||||
@@ -88,6 +86,15 @@ void repl() {
|
|||||||
Toy_freeCompiler(&compiler);
|
Toy_freeCompiler(&compiler);
|
||||||
Toy_freeParser(&parser);
|
Toy_freeParser(&parser);
|
||||||
error = false;
|
error = false;
|
||||||
|
|
||||||
|
if (initialInput) {
|
||||||
|
free((void*)initialInput);
|
||||||
|
initialInput = NULL;
|
||||||
|
|
||||||
|
if (interpreter.panic) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Toy_freeInterpreter(&interpreter);
|
Toy_freeInterpreter(&interpreter);
|
||||||
@@ -131,6 +138,14 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
//run source file
|
//run source file
|
||||||
if (Toy_commandLine.sourcefile) {
|
if (Toy_commandLine.sourcefile) {
|
||||||
|
//only works on toy files
|
||||||
|
const char* s = strrchr(Toy_commandLine.sourcefile, '.');
|
||||||
|
if (!s || strcmp(s, ".toy")) {
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "Bad file extension passed to %s (expected '.toy', found '%s')" TOY_CC_RESET, argv[0], s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//run the source file
|
||||||
Toy_runSourceFile(Toy_commandLine.sourcefile);
|
Toy_runSourceFile(Toy_commandLine.sourcefile);
|
||||||
|
|
||||||
//lib cleanup
|
//lib cleanup
|
||||||
@@ -151,6 +166,19 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
//compile source file
|
//compile source file
|
||||||
if (Toy_commandLine.compilefile && Toy_commandLine.outfile) {
|
if (Toy_commandLine.compilefile && Toy_commandLine.outfile) {
|
||||||
|
//only works on toy and tb files
|
||||||
|
const char* c = strrchr(Toy_commandLine.compilefile, '.');
|
||||||
|
if (!c || strcmp(c, ".toy")) {
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "Bad file extension passed to %s (expected '.toy', found '%s')" TOY_CC_RESET, argv[0], c);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
const char* o = strrchr(Toy_commandLine.outfile, '.');
|
||||||
|
if (!o || strcmp(o, ".tb")) {
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "Bad file extension passed to %s (expected '.tb', found '%s')" TOY_CC_RESET, argv[0], o);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//compile and save
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
const char* source = Toy_readFile(Toy_commandLine.compilefile, &size);
|
const char* source = Toy_readFile(Toy_commandLine.compilefile, &size);
|
||||||
if (!source) {
|
if (!source) {
|
||||||
@@ -166,6 +194,14 @@ int main(int argc, const char* argv[]) {
|
|||||||
|
|
||||||
//run binary
|
//run binary
|
||||||
if (Toy_commandLine.binaryfile) {
|
if (Toy_commandLine.binaryfile) {
|
||||||
|
//only works on tb files
|
||||||
|
const char* c = strrchr(Toy_commandLine.binaryfile, '.');
|
||||||
|
if (!c || strcmp(c, ".tb")) {
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "Bad file extension passed to %s (expected '.tb', found '%s')" TOY_CC_RESET, argv[0], c); //this one is never seen
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//run the binary file
|
||||||
Toy_runBinaryFile(Toy_commandLine.binaryfile);
|
Toy_runBinaryFile(Toy_commandLine.binaryfile);
|
||||||
|
|
||||||
//lib cleanup
|
//lib cleanup
|
||||||
@@ -174,7 +210,20 @@ int main(int argc, const char* argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
repl();
|
const char* initialSource = NULL;
|
||||||
|
if (Toy_commandLine.initialfile) {
|
||||||
|
//only works on toy files
|
||||||
|
const char* s = strrchr(Toy_commandLine.initialfile, '.');
|
||||||
|
if (!s || strcmp(s, ".toy")) {
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "Bad file extension passed to %s (expected '.toy', found '%s')" TOY_CC_RESET, argv[0], s);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size;
|
||||||
|
initialSource = Toy_readFile(Toy_commandLine.initialfile, &size);
|
||||||
|
}
|
||||||
|
|
||||||
|
repl(initialSource);
|
||||||
|
|
||||||
//lib cleanup
|
//lib cleanup
|
||||||
Toy_freeDriveDictionary();
|
Toy_freeDriveDictionary();
|
||||||
|
|||||||
+2
-6
@@ -1,8 +1,6 @@
|
|||||||
#include "repl_tools.h"
|
#include "repl_tools.h"
|
||||||
#include "lib_about.h"
|
#include "lib_about.h"
|
||||||
#include "lib_compound.h"
|
|
||||||
#include "lib_standard.h"
|
#include "lib_standard.h"
|
||||||
#include "lib_timer.h"
|
|
||||||
#include "lib_runner.h"
|
#include "lib_runner.h"
|
||||||
|
|
||||||
#include "toy_console_colors.h"
|
#include "toy_console_colors.h"
|
||||||
@@ -57,7 +55,7 @@ int Toy_writeFile(const char* path, const unsigned char* bytes, size_t size) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int written = fwrite(bytes, size, 1, file);
|
size_t written = fwrite(bytes, size, 1, file);
|
||||||
|
|
||||||
if (written != 1) {
|
if (written != 1) {
|
||||||
fprintf(stderr, TOY_CC_ERROR "Could not write file \"%s\"\n" TOY_CC_RESET, path);
|
fprintf(stderr, TOY_CC_ERROR "Could not write file \"%s\"\n" TOY_CC_RESET, path);
|
||||||
@@ -113,12 +111,10 @@ void Toy_runBinary(const unsigned char* tb, size_t size) {
|
|||||||
|
|
||||||
//inject the libs
|
//inject the libs
|
||||||
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
||||||
Toy_injectNativeHook(&interpreter, "compound", Toy_hookCompound);
|
|
||||||
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
||||||
Toy_injectNativeHook(&interpreter, "timer", Toy_hookTimer);
|
|
||||||
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
||||||
|
|
||||||
Toy_runInterpreter(&interpreter, tb, size);
|
Toy_runInterpreter(&interpreter, tb, (int)size);
|
||||||
Toy_freeInterpreter(&interpreter);
|
Toy_freeInterpreter(&interpreter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+29
-15
@@ -1,19 +1,21 @@
|
|||||||
//constants
|
//constants
|
||||||
var WIDTH: int const = 10;
|
var WIDTH: int const = 12;
|
||||||
var HEIGHT: int const = 10;
|
var HEIGHT: int const = 12;
|
||||||
|
|
||||||
//WIDTH * HEIGHT in size
|
//WIDTH * HEIGHT in size
|
||||||
var tiles: [[int]] const = [
|
var tiles: [[int]] const = [
|
||||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
||||||
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
||||||
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
||||||
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
||||||
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
[1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1],
|
||||||
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
[1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1],
|
||||||
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
[1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1],
|
||||||
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
[1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1],
|
||||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
[1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1],
|
||||||
|
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
|
||||||
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] //BUG: map is twisted along this diagonal
|
||||||
];
|
];
|
||||||
|
|
||||||
var tileset: [int: string] const = [
|
var tileset: [int: string] const = [
|
||||||
@@ -22,8 +24,8 @@ var tileset: [int: string] const = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
//variables
|
//variables
|
||||||
var posX: int = 5;
|
var posX: int = 4;
|
||||||
var posY: int = 5;
|
var posY: int = 4;
|
||||||
|
|
||||||
//functions
|
//functions
|
||||||
fn draw() {
|
fn draw() {
|
||||||
@@ -42,7 +44,7 @@ fn draw() {
|
|||||||
print "\n";
|
print "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move(xrel: int, yrel: int) {
|
fn moveRelative(xrel: int, yrel: int) {
|
||||||
if (xrel > 1 || xrel < -1 || yrel > 1 || yrel < -1 || (xrel != 0 && yrel != 0)) {
|
if (xrel > 1 || xrel < -1 || yrel > 1 || yrel < -1 || (xrel != 0 && yrel != 0)) {
|
||||||
print "too fast!\n";
|
print "too fast!\n";
|
||||||
return;
|
return;
|
||||||
@@ -59,3 +61,15 @@ fn move(xrel: int, yrel: int) {
|
|||||||
draw();
|
draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//wrap for easy use
|
||||||
|
var up: [int] const = [0, -1];
|
||||||
|
var down: [int] const = [0, 1];
|
||||||
|
var left: [int] const = [-1, 0];
|
||||||
|
var right: [int] const = [1, 0];
|
||||||
|
|
||||||
|
fn move(dir: [int] const) {
|
||||||
|
return moveRelative(dir[0], dir[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//initial display
|
||||||
|
move([0, 0]);
|
||||||
|
|||||||
+24
-7
@@ -1,10 +1,27 @@
|
|||||||
|
import compound;
|
||||||
|
|
||||||
var xrel: int = 0;
|
fn less(a, b) {
|
||||||
var yrel: int = 0;
|
return a < b;
|
||||||
|
}
|
||||||
|
|
||||||
if (xrel > 1 || xrel < -1 || yrel > 1 || yrel < -1) {
|
fn greater(a, b) {
|
||||||
print "outside";
|
return a > b;
|
||||||
}
|
|
||||||
else {
|
|
||||||
print "inside";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var a = [7, 2, 1, 8, 6, 3, 5, 4];
|
||||||
|
var b = [7, 2, 1, 4, 6, 3, 5, 8];
|
||||||
|
var c = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||||
|
var d = [7, 2, 1, 8, 6, 3, 5, 4];
|
||||||
|
|
||||||
|
a = a.sort(less);
|
||||||
|
b = b.sort(less);
|
||||||
|
c = c.sort(less);
|
||||||
|
d = d.sort(greater);
|
||||||
|
|
||||||
|
assert a == [1, 2, 3, 4, 5, 6, 7, 8], "array.sort(less) failed";
|
||||||
|
assert b == [1, 2, 3, 4, 5, 6, 7, 8], "array.sort(less) with pivot high failed";
|
||||||
|
assert c == [1, 2, 3, 4, 5, 6, 7, 8], "array.sort(less) pre-sorted array failed";
|
||||||
|
assert d == [8, 7, 6, 5, 4, 3, 2, 1], "array.sort(greater) failed";
|
||||||
|
|
||||||
|
|
||||||
|
print "All good";
|
||||||
|
|||||||
+10
-5
@@ -15,8 +15,6 @@ STATIC_ASSERT(sizeof(unsigned char) == 1);
|
|||||||
STATIC_ASSERT(sizeof(unsigned short) == 2);
|
STATIC_ASSERT(sizeof(unsigned short) == 2);
|
||||||
STATIC_ASSERT(sizeof(unsigned int) == 4);
|
STATIC_ASSERT(sizeof(unsigned int) == 4);
|
||||||
|
|
||||||
#ifndef TOY_EXPORT
|
|
||||||
|
|
||||||
//declare the singleton
|
//declare the singleton
|
||||||
Toy_CommandLine Toy_commandLine;
|
Toy_CommandLine Toy_commandLine;
|
||||||
|
|
||||||
@@ -30,6 +28,7 @@ void Toy_initCommandLine(int argc, const char* argv[]) {
|
|||||||
Toy_commandLine.compilefile = NULL;
|
Toy_commandLine.compilefile = NULL;
|
||||||
Toy_commandLine.outfile = "out.tb";
|
Toy_commandLine.outfile = "out.tb";
|
||||||
Toy_commandLine.source = NULL;
|
Toy_commandLine.source = NULL;
|
||||||
|
Toy_commandLine.initialfile = NULL;
|
||||||
Toy_commandLine.verbose = false;
|
Toy_commandLine.verbose = false;
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++) { //start at 1 to skip the program name
|
for (int i = 1; i < argc; i++) { //start at 1 to skip the program name
|
||||||
@@ -81,6 +80,13 @@ void Toy_initCommandLine(int argc, const char* argv[]) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((!strcmp(argv[i], "-t") || !strcmp(argv[i], "--initial")) && i + 1 < argc) {
|
||||||
|
Toy_commandLine.initialfile = (char*)argv[i + 1];
|
||||||
|
i++;
|
||||||
|
Toy_commandLine.error = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//option without a flag + ending in .tb = binary input
|
//option without a flag + ending in .tb = binary input
|
||||||
if (i < argc) {
|
if (i < argc) {
|
||||||
if (strncmp(&(argv[i][strlen(argv[i]) - 3]), ".tb", 3) == 0) {
|
if (strncmp(&(argv[i][strlen(argv[i]) - 3]), ".tb", 3) == 0) {
|
||||||
@@ -96,7 +102,7 @@ void Toy_initCommandLine(int argc, const char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Toy_usageCommandLine(int argc, const char* argv[]) {
|
void Toy_usageCommandLine(int argc, const char* argv[]) {
|
||||||
printf("Usage: %s [<file.tb> | -h | -v | [-d][-f file | -i source | -c file [-o outfile]]]\n\n", argv[0]);
|
printf("Usage: %s [ file.tb | -h | -v | -d | -f file.toy | -i source | -c file.toy -o out.tb | -t file.toy ]\n\n", argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Toy_helpCommandLine(int argc, const char* argv[]) {
|
void Toy_helpCommandLine(int argc, const char* argv[]) {
|
||||||
@@ -110,6 +116,7 @@ void Toy_helpCommandLine(int argc, const char* argv[]) {
|
|||||||
printf("-i\t| --input source\tParse, compile and execute this given string of source code.\n\n");
|
printf("-i\t| --input source\tParse, compile and execute this given string of source code.\n\n");
|
||||||
printf("-c\t| --compile filename\tParse and compile the specified source file into an output file.\n\n");
|
printf("-c\t| --compile filename\tParse and compile the specified source file into an output file.\n\n");
|
||||||
printf("-o\t| --output outfile\tName of the output file built with --compile (default: out.tb).\n\n");
|
printf("-o\t| --output outfile\tName of the output file built with --compile (default: out.tb).\n\n");
|
||||||
|
printf("-t\t| --initial filename\tStart the repl as normal, after first running the given file.\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Toy_copyrightCommandLine(int argc, const char* argv[]) {
|
void Toy_copyrightCommandLine(int argc, const char* argv[]) {
|
||||||
@@ -121,5 +128,3 @@ void Toy_copyrightCommandLine(int argc, const char* argv[]) {
|
|||||||
printf("2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n\n");
|
printf("2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n\n");
|
||||||
printf("3. This notice may not be removed or altered from any source distribution.\n\n");
|
printf("3. This notice may not be removed or altered from any source distribution.\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
+19
-13
@@ -6,22 +6,28 @@
|
|||||||
|
|
||||||
#define TOY_VERSION_MAJOR 0
|
#define TOY_VERSION_MAJOR 0
|
||||||
#define TOY_VERSION_MINOR 8
|
#define TOY_VERSION_MINOR 8
|
||||||
#define TOY_VERSION_PATCH 2
|
#define TOY_VERSION_PATCH 3
|
||||||
#define TOY_VERSION_BUILD __DATE__ " " __TIME__
|
#define TOY_VERSION_BUILD __DATE__ " " __TIME__
|
||||||
|
|
||||||
//platform-specific specifications
|
//platform/compiler-specific instructions
|
||||||
#if defined(__linux__)
|
#if defined(__linux__) || defined(__MINGW32__) || defined(__GNUC__)
|
||||||
|
|
||||||
#define TOY_API extern
|
#define TOY_API extern
|
||||||
|
|
||||||
#elif defined(_WIN32) || defined(WIN32)
|
#elif defined(_MSC_VER)
|
||||||
#define TOY_API
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
|
#define TOY_API __declspec(dllimport)
|
||||||
|
#else
|
||||||
|
#define TOY_API __declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define TOY_API
|
|
||||||
|
#define TOY_API extern
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TOY_EXPORT
|
|
||||||
//for processing the command line arguments
|
//for processing the command line arguments
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool error;
|
bool error;
|
||||||
@@ -32,14 +38,14 @@ typedef struct {
|
|||||||
char* compilefile;
|
char* compilefile;
|
||||||
char* outfile; //defaults to out.tb
|
char* outfile; //defaults to out.tb
|
||||||
char* source;
|
char* source;
|
||||||
|
char* initialfile;
|
||||||
bool verbose;
|
bool verbose;
|
||||||
} Toy_CommandLine;
|
} Toy_CommandLine;
|
||||||
|
|
||||||
extern Toy_CommandLine Toy_commandLine;
|
TOY_API Toy_CommandLine Toy_commandLine;
|
||||||
|
|
||||||
void Toy_initCommandLine(int argc, const char* argv[]);
|
TOY_API void Toy_initCommandLine(int argc, const char* argv[]);
|
||||||
|
|
||||||
void Toy_usageCommandLine(int argc, const char* argv[]);
|
TOY_API void Toy_usageCommandLine(int argc, const char* argv[]);
|
||||||
void Toy_helpCommandLine(int argc, const char* argv[]);
|
TOY_API void Toy_helpCommandLine(int argc, const char* argv[]);
|
||||||
void Toy_copyrightCommandLine(int argc, const char* argv[]);
|
TOY_API void Toy_copyrightCommandLine(int argc, const char* argv[]);
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -302,6 +302,12 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode
|
|||||||
//special case for when indexing and assigning
|
//special case for when indexing and assigning
|
||||||
if (override != TOY_OP_EOF && node->binary.opcode >= TOY_OP_VAR_ASSIGN && node->binary.opcode <= TOY_OP_VAR_MODULO_ASSIGN) {
|
if (override != TOY_OP_EOF && node->binary.opcode >= TOY_OP_VAR_ASSIGN && node->binary.opcode <= TOY_OP_VAR_MODULO_ASSIGN) {
|
||||||
Toy_writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
Toy_writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||||
|
|
||||||
|
//Special case if there's an index on both sides of the sign, just set it as indexing
|
||||||
|
if (node->binary.left->type == TOY_AST_NODE_BINARY && node->binary.right->type == TOY_AST_NODE_BINARY && node->binary.left->binary.opcode == TOY_OP_INDEX && node->binary.right->binary.opcode == TOY_OP_INDEX) {
|
||||||
|
compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_INDEX_ASSIGN; //1 byte WARNING: enum trickery
|
compiler->bytecode[compiler->count++] = (unsigned char)TOY_OP_INDEX_ASSIGN; //1 byte WARNING: enum trickery
|
||||||
compiler->bytecode[compiler->count++] = (unsigned char)node->binary.opcode; //1 byte
|
compiler->bytecode[compiler->count++] = (unsigned char)node->binary.opcode; //1 byte
|
||||||
return TOY_OP_EOF;
|
return TOY_OP_EOF;
|
||||||
@@ -315,7 +321,7 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode
|
|||||||
//return this if...
|
//return this if...
|
||||||
Toy_Opcode ret = Toy_writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
Toy_Opcode ret = Toy_writeCompilerWithJumps(compiler, node->binary.right, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
|
||||||
|
|
||||||
if (node->binary.opcode == TOY_OP_INDEX && rootNode->type == TOY_AST_NODE_BINARY && (rootNode->binary.opcode >= TOY_OP_VAR_ASSIGN && rootNode->binary.opcode <= TOY_OP_VAR_MODULO_ASSIGN)) { //range-based check for assignment type
|
if (node->binary.opcode == TOY_OP_INDEX && rootNode->type == TOY_AST_NODE_BINARY && (rootNode->binary.opcode >= TOY_OP_VAR_ASSIGN && rootNode->binary.opcode <= TOY_OP_VAR_MODULO_ASSIGN) && rootNode->binary.right != node) { //range-based check for assignment type; make sure the index is on the left of the assignment symbol
|
||||||
return TOY_OP_INDEX_ASSIGN_INTERMEDIATE;
|
return TOY_OP_INDEX_ASSIGN_INTERMEDIATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1167,7 +1173,7 @@ static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size
|
|||||||
case TOY_LITERAL_FUNCTION_INTERMEDIATE: {
|
case TOY_LITERAL_FUNCTION_INTERMEDIATE: {
|
||||||
//extract the compiler
|
//extract the compiler
|
||||||
Toy_Literal fn = compiler->literalCache.literals[i];
|
Toy_Literal fn = compiler->literalCache.literals[i];
|
||||||
void* fnCompiler = TOY_AS_FUNCTION(fn).bytecode; //store the compiler here for now
|
void* fnCompiler = TOY_AS_FUNCTION(fn).inner.bytecode; //store the compiler here for now
|
||||||
|
|
||||||
//collate the function into bytecode (without header)
|
//collate the function into bytecode (without header)
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
//NOTE: you need both font AND background for these to work
|
//NOTE: you need both font AND background for these to work
|
||||||
|
|
||||||
|
//platform/compiler-specific instructions
|
||||||
|
#if defined(__linux__) || defined(__MINGW32__) || defined(__GNUC__)
|
||||||
|
|
||||||
//fonts color
|
//fonts color
|
||||||
#define TOY_CC_FONT_BLACK "\033[30;"
|
#define TOY_CC_FONT_BLACK "\033[30;"
|
||||||
#define TOY_CC_FONT_RED "\033[31;"
|
#define TOY_CC_FONT_RED "\033[31;"
|
||||||
@@ -28,3 +31,34 @@
|
|||||||
#define TOY_CC_WARN TOY_CC_FONT_YELLOW TOY_CC_BACK_BLACK
|
#define TOY_CC_WARN TOY_CC_FONT_YELLOW TOY_CC_BACK_BLACK
|
||||||
#define TOY_CC_ERROR TOY_CC_FONT_RED TOY_CC_BACK_BLACK
|
#define TOY_CC_ERROR TOY_CC_FONT_RED TOY_CC_BACK_BLACK
|
||||||
#define TOY_CC_RESET "\033[0m"
|
#define TOY_CC_RESET "\033[0m"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
//fonts color
|
||||||
|
#define TOY_CC_FONT_BLACK
|
||||||
|
#define TOY_CC_FONT_RED
|
||||||
|
#define TOY_CC_FONT_GREEN
|
||||||
|
#define TOY_CC_FONT_YELLOW
|
||||||
|
#define TOY_CC_FONT_BLUE
|
||||||
|
#define TOY_CC_FONT_PURPLE
|
||||||
|
#define TOY_CC_FONT_DGREEN
|
||||||
|
#define TOY_CC_FONT_WHITE
|
||||||
|
#define TOY_CC_FONT_CYAN
|
||||||
|
|
||||||
|
//background color
|
||||||
|
#define TOY_CC_BACK_BLACK
|
||||||
|
#define TOY_CC_BACK_RED
|
||||||
|
#define TOY_CC_BACK_GREEN
|
||||||
|
#define TOY_CC_BACK_YELLOW
|
||||||
|
#define TOY_CC_BACK_BLUE
|
||||||
|
#define TOY_CC_BACK_PURPLE
|
||||||
|
#define TOY_CC_BACK_DGREEN
|
||||||
|
#define TOY_CC_BACK_WHITE
|
||||||
|
|
||||||
|
//useful
|
||||||
|
#define TOY_CC_NOTICE TOY_CC_FONT_GREEN TOY_CC_BACK_BLACK
|
||||||
|
#define TOY_CC_WARN TOY_CC_FONT_YELLOW TOY_CC_BACK_BLACK
|
||||||
|
#define TOY_CC_ERROR TOY_CC_FONT_RED TOY_CC_BACK_BLACK
|
||||||
|
#define TOY_CC_RESET
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1254,8 +1254,8 @@ bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_Liter
|
|||||||
//init the inner interpreter manually
|
//init the inner interpreter manually
|
||||||
Toy_initLiteralArray(&inner.literalCache);
|
Toy_initLiteralArray(&inner.literalCache);
|
||||||
inner.scope = Toy_pushScope(func.as.function.scope);
|
inner.scope = Toy_pushScope(func.as.function.scope);
|
||||||
inner.bytecode = TOY_AS_FUNCTION(func).bytecode;
|
inner.bytecode = TOY_AS_FUNCTION(func).inner.bytecode;
|
||||||
inner.length = TOY_AS_FUNCTION(func).length;
|
inner.length = TOY_AS_FUNCTION_BYTECODE_LENGTH(func);
|
||||||
inner.count = 0;
|
inner.count = 0;
|
||||||
inner.codeStart = -1;
|
inner.codeStart = -1;
|
||||||
inner.depth = interpreter->depth + 1;
|
inner.depth = interpreter->depth + 1;
|
||||||
@@ -1507,7 +1507,7 @@ static bool execImport(Toy_Interpreter* interpreter) {
|
|||||||
if (!Toy_existsLiteralDictionary(interpreter->hooks, identifier)) {
|
if (!Toy_existsLiteralDictionary(interpreter->hooks, identifier)) {
|
||||||
interpreter->errorOutput("Unknown library name in import statement: ");
|
interpreter->errorOutput("Unknown library name in import statement: ");
|
||||||
Toy_printLiteralCustom(identifier, interpreter->errorOutput);
|
Toy_printLiteralCustom(identifier, interpreter->errorOutput);
|
||||||
interpreter->errorOutput("\"\n");
|
interpreter->errorOutput("\n");
|
||||||
|
|
||||||
Toy_freeLiteral(alias);
|
Toy_freeLiteral(alias);
|
||||||
Toy_freeLiteral(identifier);
|
Toy_freeLiteral(identifier);
|
||||||
@@ -2356,7 +2356,7 @@ void Toy_initInterpreter(Toy_Interpreter* interpreter) {
|
|||||||
Toy_resetInterpreter(interpreter);
|
Toy_resetInterpreter(interpreter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Toy_runInterpreter(Toy_Interpreter* interpreter, const unsigned char* bytecode, int length) {
|
void Toy_runInterpreter(Toy_Interpreter* interpreter, const unsigned char* bytecode, size_t length) {
|
||||||
//initialize here instead of initInterpreter()
|
//initialize here instead of initInterpreter()
|
||||||
Toy_initLiteralArray(&interpreter->literalCache);
|
Toy_initLiteralArray(&interpreter->literalCache);
|
||||||
interpreter->bytecode = NULL;
|
interpreter->bytecode = NULL;
|
||||||
|
|||||||
@@ -48,6 +48,6 @@ TOY_API void Toy_setInterpreterError(Toy_Interpreter* interpreter, Toy_PrintFn e
|
|||||||
|
|
||||||
//main access
|
//main access
|
||||||
TOY_API void Toy_initInterpreter(Toy_Interpreter* interpreter); //start of program
|
TOY_API void Toy_initInterpreter(Toy_Interpreter* interpreter); //start of program
|
||||||
TOY_API void Toy_runInterpreter(Toy_Interpreter* interpreter, const unsigned char* bytecode, int length); //run the code
|
TOY_API void Toy_runInterpreter(Toy_Interpreter* interpreter, const unsigned char* bytecode, size_t length); //run the code
|
||||||
TOY_API void Toy_resetInterpreter(Toy_Interpreter* interpreter); //use this to reset the interpreter's environment between runs
|
TOY_API void Toy_resetInterpreter(Toy_Interpreter* interpreter); //use this to reset the interpreter's environment between runs
|
||||||
TOY_API void Toy_freeInterpreter(Toy_Interpreter* interpreter); //end of program
|
TOY_API void Toy_freeInterpreter(Toy_Interpreter* interpreter); //end of program
|
||||||
|
|||||||
+3
-3
@@ -21,9 +21,9 @@ typedef struct {
|
|||||||
} Toy_Token;
|
} Toy_Token;
|
||||||
|
|
||||||
TOY_API void Toy_initLexer(Toy_Lexer* lexer, const char* source);
|
TOY_API void Toy_initLexer(Toy_Lexer* lexer, const char* source);
|
||||||
Toy_Token Toy_scanLexer(Toy_Lexer* lexer);
|
TOY_API Toy_Token Toy_scanLexer(Toy_Lexer* lexer);
|
||||||
|
|
||||||
//for debugging
|
//for debugging
|
||||||
void Toy_printToken(Toy_Token* token);
|
TOY_API void Toy_printToken(Toy_Token* token);
|
||||||
|
|
||||||
void Toy_private_setComments(Toy_Lexer* lexer, bool enabled);
|
TOY_API void Toy_private_setComments(Toy_Lexer* lexer, bool enabled);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ void Toy_freeLiteral(Toy_Literal literal) {
|
|||||||
if (TOY_IS_FUNCTION(literal)) {
|
if (TOY_IS_FUNCTION(literal)) {
|
||||||
Toy_popScope(TOY_AS_FUNCTION(literal).scope);
|
Toy_popScope(TOY_AS_FUNCTION(literal).scope);
|
||||||
TOY_AS_FUNCTION(literal).scope = NULL;
|
TOY_AS_FUNCTION(literal).scope = NULL;
|
||||||
TOY_FREE_ARRAY(unsigned char, TOY_AS_FUNCTION(literal).bytecode, TOY_AS_FUNCTION(literal).length);
|
TOY_FREE_ARRAY(unsigned char, TOY_AS_FUNCTION(literal).inner.bytecode, TOY_AS_FUNCTION_BYTECODE_LENGTH(literal));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TOY_IS_TYPE(literal)) {
|
if (TOY_IS_TYPE(literal)) {
|
||||||
@@ -84,11 +84,11 @@ bool Toy_private_isTruthy(Toy_Literal x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Toy_Literal Toy_private_toStringLiteral(Toy_RefString* ptr) {
|
Toy_Literal Toy_private_toStringLiteral(Toy_RefString* ptr) {
|
||||||
return ((Toy_Literal){TOY_LITERAL_STRING, { .string.ptr = ptr }});
|
return ((Toy_Literal){{ .string.ptr = ptr },TOY_LITERAL_STRING, 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
Toy_Literal Toy_private_toIdentifierLiteral(Toy_RefString* ptr) {
|
Toy_Literal Toy_private_toIdentifierLiteral(Toy_RefString* ptr) {
|
||||||
return ((Toy_Literal){TOY_LITERAL_IDENTIFIER,{ .identifier.ptr = ptr, .identifier.hash = hashString(Toy_toCString(ptr), Toy_lengthRefString(ptr)) }});
|
return ((Toy_Literal){{ .identifier.ptr = ptr, .identifier.hash = hashString(Toy_toCString(ptr), Toy_lengthRefString(ptr)) },TOY_LITERAL_IDENTIFIER, 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
Toy_Literal* Toy_private_typePushSubtype(Toy_Literal* lit, Toy_Literal subtype) {
|
Toy_Literal* Toy_private_typePushSubtype(Toy_Literal* lit, Toy_Literal subtype) {
|
||||||
@@ -145,10 +145,10 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case TOY_LITERAL_FUNCTION: {
|
case TOY_LITERAL_FUNCTION: {
|
||||||
unsigned char* buffer = TOY_ALLOCATE(unsigned char, TOY_AS_FUNCTION(original).length);
|
unsigned char* buffer = TOY_ALLOCATE(unsigned char, TOY_AS_FUNCTION_BYTECODE_LENGTH(original));
|
||||||
memcpy(buffer, TOY_AS_FUNCTION(original).bytecode, TOY_AS_FUNCTION(original).length);
|
memcpy(buffer, TOY_AS_FUNCTION(original).inner.bytecode, TOY_AS_FUNCTION_BYTECODE_LENGTH(original));
|
||||||
|
|
||||||
Toy_Literal literal = TOY_TO_FUNCTION_LITERAL(buffer, TOY_AS_FUNCTION(original).length);
|
Toy_Literal literal = TOY_TO_FUNCTION_LITERAL(buffer, TOY_AS_FUNCTION_BYTECODE_LENGTH(original));
|
||||||
TOY_AS_FUNCTION(literal).scope = Toy_copyScope(TOY_AS_FUNCTION(original).scope);
|
TOY_AS_FUNCTION(literal).scope = Toy_copyScope(TOY_AS_FUNCTION(original).scope);
|
||||||
|
|
||||||
return literal;
|
return literal;
|
||||||
|
|||||||
+47
-41
@@ -39,45 +39,49 @@ typedef enum {
|
|||||||
} Toy_LiteralType;
|
} Toy_LiteralType;
|
||||||
|
|
||||||
typedef struct Toy_Literal {
|
typedef struct Toy_Literal {
|
||||||
Toy_LiteralType type;
|
|
||||||
union {
|
union {
|
||||||
bool boolean;
|
bool boolean; //1
|
||||||
int integer;
|
int integer; //4
|
||||||
float number;
|
float number;//4
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Toy_RefString* ptr;
|
Toy_RefString* ptr; //8
|
||||||
//string hash?
|
//string hash?
|
||||||
} string;
|
} string; //8
|
||||||
|
|
||||||
void* array;
|
void* array; //8
|
||||||
void* dictionary;
|
void* dictionary; //8
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
void* bytecode;
|
union {
|
||||||
Toy_NativeFn native; //already a pointer
|
void* bytecode; //8
|
||||||
Toy_HookFn hook; //already a pointer
|
Toy_NativeFn native; //8
|
||||||
void* scope;
|
Toy_HookFn hook; //8
|
||||||
int length;
|
} inner; //8
|
||||||
} function;
|
void* scope; //8
|
||||||
|
} function; //16
|
||||||
|
|
||||||
struct { //for variable names
|
struct { //for variable names
|
||||||
Toy_RefString* ptr;
|
Toy_RefString* ptr; //8
|
||||||
int hash;
|
int hash; //4
|
||||||
} identifier;
|
} identifier; //16
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Toy_LiteralType typeOf;
|
void* subtypes; //8
|
||||||
bool constant;
|
Toy_LiteralType typeOf; //4
|
||||||
void* subtypes; //for nested types caused by compounds
|
unsigned char capacity; //1
|
||||||
int capacity;
|
unsigned char count; //1
|
||||||
int count;
|
bool constant; //1
|
||||||
} type;
|
} type; //16
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
void* ptr;
|
void* ptr; //8
|
||||||
int tag;
|
int tag; //4
|
||||||
} opaque;
|
} opaque; //16
|
||||||
} as;
|
} as; //16
|
||||||
|
|
||||||
|
Toy_LiteralType type; //4
|
||||||
|
int bytecodeLength; //4 - shenanigans with byte alignment reduces the size of Toy_Literal
|
||||||
} Toy_Literal;
|
} Toy_Literal;
|
||||||
|
|
||||||
#define TOY_IS_NULL(value) ((value).type == TOY_LITERAL_NULL)
|
#define TOY_IS_NULL(value) ((value).type == TOY_LITERAL_NULL)
|
||||||
@@ -101,34 +105,36 @@ typedef struct Toy_Literal {
|
|||||||
#define TOY_AS_ARRAY(value) ((Toy_LiteralArray*)((value).as.array))
|
#define TOY_AS_ARRAY(value) ((Toy_LiteralArray*)((value).as.array))
|
||||||
#define TOY_AS_DICTIONARY(value) ((Toy_LiteralDictionary*)((value).as.dictionary))
|
#define TOY_AS_DICTIONARY(value) ((Toy_LiteralDictionary*)((value).as.dictionary))
|
||||||
#define TOY_AS_FUNCTION(value) ((value).as.function)
|
#define TOY_AS_FUNCTION(value) ((value).as.function)
|
||||||
#define TOY_AS_FUNCTION_NATIVE(value) ((value).as.function.native)
|
#define TOY_AS_FUNCTION_NATIVE(value) ((value).as.function.inner.native)
|
||||||
#define TOY_AS_FUNCTION_HOOK(value) ((value).as.function.hook)
|
#define TOY_AS_FUNCTION_HOOK(value) ((value).as.function.inner.hook)
|
||||||
#define TOY_AS_IDENTIFIER(value) ((value).as.identifier.ptr)
|
#define TOY_AS_IDENTIFIER(value) ((value).as.identifier.ptr)
|
||||||
#define TOY_AS_TYPE(value) ((value).as.type)
|
#define TOY_AS_TYPE(value) ((value).as.type)
|
||||||
#define TOY_AS_OPAQUE(value) ((value).as.opaque.ptr)
|
#define TOY_AS_OPAQUE(value) ((value).as.opaque.ptr)
|
||||||
|
|
||||||
#define TOY_TO_NULL_LITERAL ((Toy_Literal){TOY_LITERAL_NULL, { .integer = 0 }})
|
#define TOY_TO_NULL_LITERAL ((Toy_Literal){{ .integer = 0 }, TOY_LITERAL_NULL, 0})
|
||||||
#define TOY_TO_BOOLEAN_LITERAL(value) ((Toy_Literal){TOY_LITERAL_BOOLEAN, { .boolean = value }})
|
#define TOY_TO_BOOLEAN_LITERAL(value) ((Toy_Literal){{ .boolean = value }, TOY_LITERAL_BOOLEAN, 0})
|
||||||
#define TOY_TO_INTEGER_LITERAL(value) ((Toy_Literal){TOY_LITERAL_INTEGER, { .integer = value }})
|
#define TOY_TO_INTEGER_LITERAL(value) ((Toy_Literal){{ .integer = value }, TOY_LITERAL_INTEGER, 0})
|
||||||
#define TOY_TO_FLOAT_LITERAL(value) ((Toy_Literal){TOY_LITERAL_FLOAT, { .number = value }})
|
#define TOY_TO_FLOAT_LITERAL(value) ((Toy_Literal){{ .number = value }, TOY_LITERAL_FLOAT, 0})
|
||||||
#define TOY_TO_STRING_LITERAL(value) Toy_private_toStringLiteral(value)
|
#define TOY_TO_STRING_LITERAL(value) Toy_private_toStringLiteral(value)
|
||||||
#define TOY_TO_ARRAY_LITERAL(value) ((Toy_Literal){TOY_LITERAL_ARRAY, { .array = value }})
|
#define TOY_TO_ARRAY_LITERAL(value) ((Toy_Literal){{ .array = value }, TOY_LITERAL_ARRAY, 0})
|
||||||
#define TOY_TO_DICTIONARY_LITERAL(value) ((Toy_Literal){TOY_LITERAL_DICTIONARY, { .dictionary = value }})
|
#define TOY_TO_DICTIONARY_LITERAL(value) ((Toy_Literal){{ .dictionary = value }, TOY_LITERAL_DICTIONARY, 0})
|
||||||
#define TOY_TO_FUNCTION_LITERAL(value, l) ((Toy_Literal){TOY_LITERAL_FUNCTION, { .function.bytecode = value, .function.scope = NULL, .function.length = l }})
|
#define TOY_TO_FUNCTION_LITERAL(value, l) ((Toy_Literal){{ .function.inner.bytecode = value, .function.scope = NULL }, TOY_LITERAL_FUNCTION, l})
|
||||||
#define TOY_TO_FUNCTION_NATIVE_LITERAL(value) ((Toy_Literal){TOY_LITERAL_FUNCTION_NATIVE, { .function.native = value, .function.scope = NULL, .function.length = 0 }})
|
#define TOY_TO_FUNCTION_NATIVE_LITERAL(value) ((Toy_Literal){{ .function.inner.native = value, .function.scope = NULL }, TOY_LITERAL_FUNCTION_NATIVE, 0})
|
||||||
#define TOY_TO_FUNCTION_HOOK_LITERAL(value) ((Toy_Literal){TOY_LITERAL_FUNCTION_HOOK, { .function.hook = value, .function.scope = NULL, .function.length = 0 }})
|
#define TOY_TO_FUNCTION_HOOK_LITERAL(value) ((Toy_Literal){{ .function.inner.hook = value, .function.scope = NULL }, TOY_LITERAL_FUNCTION_HOOK, 0})
|
||||||
#define TOY_TO_IDENTIFIER_LITERAL(value) Toy_private_toIdentifierLiteral(value)
|
#define TOY_TO_IDENTIFIER_LITERAL(value) Toy_private_toIdentifierLiteral(value)
|
||||||
#define TOY_TO_TYPE_LITERAL(value, c) ((Toy_Literal){ TOY_LITERAL_TYPE, { .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }})
|
#define TOY_TO_TYPE_LITERAL(value, c) ((Toy_Literal){{ .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }, TOY_LITERAL_TYPE, 0})
|
||||||
#define TOY_TO_OPAQUE_LITERAL(value, t) ((Toy_Literal){ TOY_LITERAL_OPAQUE, { .opaque.ptr = value, .opaque.tag = t }})
|
#define TOY_TO_OPAQUE_LITERAL(value, t) ((Toy_Literal){{ .opaque.ptr = value, .opaque.tag = t }, TOY_LITERAL_OPAQUE, 0})
|
||||||
|
|
||||||
//BUGFIX: For blank indexing
|
//BUGFIX: For blank indexing
|
||||||
#define TOY_IS_INDEX_BLANK(value) ((value).type == TOY_LITERAL_INDEX_BLANK)
|
#define TOY_IS_INDEX_BLANK(value) ((value).type == TOY_LITERAL_INDEX_BLANK)
|
||||||
#define TOY_TO_INDEX_BLANK_LITERAL ((Toy_Literal){TOY_LITERAL_INDEX_BLANK, { .integer = 0 }})
|
#define TOY_TO_INDEX_BLANK_LITERAL ((Toy_Literal){{ .integer = 0 }, TOY_LITERAL_INDEX_BLANK, 0})
|
||||||
|
|
||||||
TOY_API void Toy_freeLiteral(Toy_Literal literal);
|
TOY_API void Toy_freeLiteral(Toy_Literal literal);
|
||||||
|
|
||||||
#define TOY_IS_TRUTHY(x) Toy_private_isTruthy(x)
|
#define TOY_IS_TRUTHY(x) Toy_private_isTruthy(x)
|
||||||
|
|
||||||
|
#define TOY_AS_FUNCTION_BYTECODE_LENGTH(lit) ((lit).bytecodeLength)
|
||||||
|
|
||||||
#define TOY_MAX_STRING_LENGTH 4096
|
#define TOY_MAX_STRING_LENGTH 4096
|
||||||
#define TOY_HASH_I(lit) ((lit).as.identifier.hash)
|
#define TOY_HASH_I(lit) ((lit).as.identifier.hash)
|
||||||
#define TOY_TYPE_PUSH_SUBTYPE(lit, subtype) Toy_private_typePushSubtype(lit, subtype)
|
#define TOY_TYPE_PUSH_SUBTYPE(lit, subtype) Toy_private_typePushSubtype(lit, subtype)
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@
|
|||||||
#define TOY_FREE_ARRAY(type, pointer, oldCount) Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), 0)
|
#define TOY_FREE_ARRAY(type, pointer, oldCount) Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), 0)
|
||||||
|
|
||||||
//implementation details
|
//implementation details
|
||||||
void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize);
|
TOY_API void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize);
|
||||||
|
|
||||||
//assign the memory allocator
|
//assign the memory allocator
|
||||||
typedef void* (*Toy_MemoryAllocatorFn)(void* pointer, size_t oldSize, size_t newSize);
|
typedef void* (*Toy_MemoryAllocatorFn)(void* pointer, size_t oldSize, size_t newSize);
|
||||||
|
|||||||
+12
-10
@@ -3,6 +3,8 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "toy_common.h"
|
||||||
|
|
||||||
//memory allocation hook
|
//memory allocation hook
|
||||||
typedef void* (*Toy_RefStringAllocatorFn)(void* pointer, size_t oldSize, size_t newSize);
|
typedef void* (*Toy_RefStringAllocatorFn)(void* pointer, size_t oldSize, size_t newSize);
|
||||||
void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn);
|
void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn);
|
||||||
@@ -15,13 +17,13 @@ typedef struct Toy_RefString {
|
|||||||
} Toy_RefString;
|
} Toy_RefString;
|
||||||
|
|
||||||
//API
|
//API
|
||||||
Toy_RefString* Toy_createRefString(const char* cstring);
|
TOY_API Toy_RefString* Toy_createRefString(const char* cstring);
|
||||||
Toy_RefString* Toy_createRefStringLength(const char* cstring, size_t length);
|
TOY_API Toy_RefString* Toy_createRefStringLength(const char* cstring, size_t length);
|
||||||
void Toy_deleteRefString(Toy_RefString* refString);
|
TOY_API void Toy_deleteRefString(Toy_RefString* refString);
|
||||||
int Toy_countRefString(Toy_RefString* refString);
|
TOY_API int Toy_countRefString(Toy_RefString* refString);
|
||||||
size_t Toy_lengthRefString(Toy_RefString* refString);
|
TOY_API size_t Toy_lengthRefString(Toy_RefString* refString);
|
||||||
Toy_RefString* Toy_copyRefString(Toy_RefString* refString);
|
TOY_API Toy_RefString* Toy_copyRefString(Toy_RefString* refString);
|
||||||
Toy_RefString* Toy_deepCopyRefString(Toy_RefString* refString);
|
TOY_API Toy_RefString* Toy_deepCopyRefString(Toy_RefString* refString);
|
||||||
const char* Toy_toCString(Toy_RefString* refString);
|
TOY_API const char* Toy_toCString(Toy_RefString* refString);
|
||||||
bool Toy_equalsRefString(Toy_RefString* lhs, Toy_RefString* rhs);
|
TOY_API bool Toy_equalsRefString(Toy_RefString* lhs, Toy_RefString* rhs);
|
||||||
bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring);
|
TOY_API bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring);
|
||||||
|
|||||||
+8
-8
@@ -10,16 +10,16 @@ typedef struct Toy_Scope {
|
|||||||
int references; //how many scopes point here
|
int references; //how many scopes point here
|
||||||
} Toy_Scope;
|
} Toy_Scope;
|
||||||
|
|
||||||
Toy_Scope* Toy_pushScope(Toy_Scope* scope);
|
TOY_API Toy_Scope* Toy_pushScope(Toy_Scope* scope);
|
||||||
Toy_Scope* Toy_popScope(Toy_Scope* scope);
|
TOY_API Toy_Scope* Toy_popScope(Toy_Scope* scope);
|
||||||
Toy_Scope* Toy_copyScope(Toy_Scope* original);
|
TOY_API Toy_Scope* Toy_copyScope(Toy_Scope* original);
|
||||||
|
|
||||||
//returns false if error
|
//returns false if error
|
||||||
bool Toy_declareScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal type);
|
TOY_API bool Toy_declareScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal type);
|
||||||
bool Toy_isDelcaredScopeVariable(Toy_Scope* scope, Toy_Literal key);
|
TOY_API bool Toy_isDelcaredScopeVariable(Toy_Scope* scope, Toy_Literal key);
|
||||||
|
|
||||||
//return false if undefined
|
//return false if undefined
|
||||||
bool Toy_setScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal value, bool constCheck);
|
TOY_API bool Toy_setScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal value, bool constCheck);
|
||||||
bool Toy_getScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal* value);
|
TOY_API bool Toy_getScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal* value);
|
||||||
|
|
||||||
Toy_Literal Toy_getScopeType(Toy_Scope* scope, Toy_Literal key);
|
TOY_API Toy_Literal Toy_getScopeType(Toy_Scope* scope, Toy_Literal key);
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
This ensures that when indexing on both sides of an assignment,
|
||||||
|
it works correctly.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
var b = [4, 5, 6];
|
||||||
|
|
||||||
|
a[1] = b[1];
|
||||||
|
|
||||||
|
assert a == [1, 5, 3], "index assignment both failed";
|
||||||
|
|
||||||
|
print "All good";
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Compiler note:
|
||||||
|
This is also to test a specific element in the compiler.
|
||||||
|
It ensures that when doing indexing and assignment in one statement,
|
||||||
|
the index is NOT on the right. If it is, then it is treated like a normal
|
||||||
|
assignment.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
//polyfill the _insert function
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
|
||||||
|
var b = a[1];
|
||||||
|
|
||||||
|
assert b == 2, "index assignment left failed";
|
||||||
|
|
||||||
|
|
||||||
|
print "All good";
|
||||||
@@ -1,280 +0,0 @@
|
|||||||
import compound;
|
|
||||||
|
|
||||||
//test concat
|
|
||||||
{
|
|
||||||
//test array concat
|
|
||||||
{
|
|
||||||
var a = [1, 2, 3];
|
|
||||||
var b = [4, 5, 6];
|
|
||||||
|
|
||||||
var c = a.concat(b).concat(b);
|
|
||||||
|
|
||||||
assert c == [1, 2, 3, 4, 5, 6, 4, 5, 6], "array.concat() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
//test dictionary concat
|
|
||||||
{
|
|
||||||
var a = ["one" : 1, "two": 2, "three": 3];
|
|
||||||
var b = ["four" : 4, "five": 5, "six": 6];
|
|
||||||
|
|
||||||
var c = a.concat(b);
|
|
||||||
|
|
||||||
assert c.length() == 6, "dictionary.concat().length() failed";
|
|
||||||
|
|
||||||
assert c == ["one" : 1, "two": 2, "three": 3, "four" : 4, "five": 5, "six": 6], "dictionary.concat() comparison failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
//test dictionary concat with clashing keys
|
|
||||||
{
|
|
||||||
var a = ["one" : 1, "two": 2, "three": 3, "random": 1];
|
|
||||||
var b = ["four" : 4, "five": 5, "six": 6, "random": 2];
|
|
||||||
|
|
||||||
var c = a.concat(b);
|
|
||||||
|
|
||||||
assert c["random"] == 1, "dictionary.concat() clashing keys failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
//test string concat
|
|
||||||
{
|
|
||||||
var a = "foo";
|
|
||||||
var b = "bar";
|
|
||||||
|
|
||||||
var c = a.concat(b);
|
|
||||||
|
|
||||||
assert c == "foobar", "string.concat() failed";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test containsKey
|
|
||||||
{
|
|
||||||
var d = ["one": 1, "two": 2];
|
|
||||||
|
|
||||||
assert d.containsKey("one") == true, "dictionary.containsKey() == true failed";
|
|
||||||
assert d.containsKey("three") == false, "dictionary.containsKey() == false failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test containsValue
|
|
||||||
{
|
|
||||||
var a = [1, 2, 3];
|
|
||||||
var d = ["one": 1, "two": 2];
|
|
||||||
|
|
||||||
assert a.containsValue(1) == true, "array.containsValue() == true failed";
|
|
||||||
assert a.containsValue(5) == false, "array.containsValue() == false failed";
|
|
||||||
assert d.containsValue(1) == true, "dictionary.containsValue() == true failed";
|
|
||||||
assert d.containsValue(3) == false, "dictionary.containsValue() == false failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test every
|
|
||||||
{
|
|
||||||
var a = [1, 2, 3];
|
|
||||||
var d = ["one": 1, "two": 2];
|
|
||||||
|
|
||||||
var counter = 0;
|
|
||||||
fn f(k, v) {
|
|
||||||
counter++;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert a.every(f) == true, "array.every() == true failed";
|
|
||||||
assert d.every(f) == true, "dictionary.every() == true failed";
|
|
||||||
|
|
||||||
assert counter == 5, "Unexpected number of calls for _every() == true";
|
|
||||||
|
|
||||||
counter = 0;
|
|
||||||
a[1] = false;
|
|
||||||
d["two"] = false;
|
|
||||||
|
|
||||||
assert a.every(f) == false, "array.every() == false failed";
|
|
||||||
assert d.every(f) == false, "dictionary.every() == false failed";
|
|
||||||
|
|
||||||
assert counter == 4, "Unexpected number of calls for _every() == false";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test filter
|
|
||||||
{
|
|
||||||
var a = [1, 2, 3, 4];
|
|
||||||
var d = ["one": 1, "two": 2, "three": 3, "four": 4];
|
|
||||||
|
|
||||||
fn f(k, v) {
|
|
||||||
return v % 2 == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert a.filter(f) == [2, 4], "array.filter() failed";
|
|
||||||
assert d.filter(f) == ["two": 2, "four": 4], "dictionary.filter() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test forEach
|
|
||||||
{
|
|
||||||
var counter = 0;
|
|
||||||
|
|
||||||
fn p(k, v) {
|
|
||||||
counter++;
|
|
||||||
print string k + ": " + string v;
|
|
||||||
}
|
|
||||||
|
|
||||||
var a = ["a", "b"];
|
|
||||||
var d = ["foo": 1, "bar": 2, "bazz": 3, "fizz": 4];
|
|
||||||
|
|
||||||
a.forEach(p);
|
|
||||||
assert counter == 2, "forEach ran an unusual number of times";
|
|
||||||
|
|
||||||
counter = 0;
|
|
||||||
d.forEach(p);
|
|
||||||
assert counter == 4, "forEach ran an unusual number of times";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test getKeys
|
|
||||||
{
|
|
||||||
var d = ["foo": 1, "bar": 2];
|
|
||||||
|
|
||||||
var a = d.getKeys();
|
|
||||||
|
|
||||||
assert a.length() == 2, "_getKeys() length failed";
|
|
||||||
|
|
||||||
//NOTE: dependant on hash algorithm
|
|
||||||
assert a == ["bar", "foo"], "_getKeys() result failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test getValues
|
|
||||||
{
|
|
||||||
var d = ["foo": 1, "bar": 2];
|
|
||||||
|
|
||||||
var a = d.getValues();
|
|
||||||
|
|
||||||
assert a.length() == 2, "_getValues() length failed";
|
|
||||||
|
|
||||||
//NOTE: dependant on hash algorithm
|
|
||||||
assert a == [2, 1], "_getValues() result failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test map
|
|
||||||
{
|
|
||||||
//test map with toy functions
|
|
||||||
{
|
|
||||||
fn increment(k, v) {
|
|
||||||
return v + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var a = [1, 2, 3];
|
|
||||||
var d = ["four": 4, "five": 5, "six": 6];
|
|
||||||
|
|
||||||
assert a.map(increment).map(increment).map(increment) == [4,5,6], "array.map() failed";
|
|
||||||
assert d.map(increment).map(increment).map(increment) == [8,9,7], "dictionary.map() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
//test map with native functions
|
|
||||||
{
|
|
||||||
//TODO: write some native functions for use with map
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test reduce
|
|
||||||
{
|
|
||||||
var a = [1, 2, 3, 4];
|
|
||||||
var d = ["one": 1, "two": 2, "three": 3, "four": 4];
|
|
||||||
|
|
||||||
fn f(acc, k, v) {
|
|
||||||
return acc + v;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert a.reduce(0, f) == 10, "array.reduce() failed";
|
|
||||||
assert d.reduce(0, f) == 10, "dictionary.reduce() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test some
|
|
||||||
{
|
|
||||||
var a = [false, false, false];
|
|
||||||
var d = ["one": false, "two": false];
|
|
||||||
|
|
||||||
var counter = 0;
|
|
||||||
fn f(k, v) {
|
|
||||||
counter++;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert a.some(f) == false, "array.some() == false failed";
|
|
||||||
assert d.some(f) == false, "dictionary.some() == false failed";
|
|
||||||
|
|
||||||
assert counter == 5, "Unexpected number of calls for _some() == false";
|
|
||||||
|
|
||||||
counter = 0;
|
|
||||||
a[1] = true;
|
|
||||||
d["two"] = true;
|
|
||||||
|
|
||||||
assert a.some(f) == true, "array.some() == true failed";
|
|
||||||
assert d.some(f) == true, "dictionary.some() == true failed";
|
|
||||||
|
|
||||||
assert counter == 4, "Unexpected number of calls for _some() == true";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test toLower
|
|
||||||
{
|
|
||||||
assert "Hello World".toLower() == "hello world", "_toLower() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test toString
|
|
||||||
{
|
|
||||||
var a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
|
|
||||||
|
|
||||||
var s = a.toString();
|
|
||||||
|
|
||||||
assert s == "[[1,2,3],[4,5,6],[7,8,9]]", "array._toString() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test toUpper
|
|
||||||
{
|
|
||||||
assert "Hello World".toUpper() == "HELLO WORLD", "_toUpper() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//test trim defaults
|
|
||||||
{
|
|
||||||
{
|
|
||||||
//test a bunch
|
|
||||||
fn test(s, pass) {
|
|
||||||
var result = s.trim();
|
|
||||||
assert result == pass, "_trim(" + result + ") failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
test("hello world", "hello world");
|
|
||||||
test(" hello world", "hello world");
|
|
||||||
test("hello world ", "hello world");
|
|
||||||
test(" hello world ", "hello world");
|
|
||||||
test(" hello world", "hello world");
|
|
||||||
test("hello world ", "hello world");
|
|
||||||
test(" hello world ", "hello world");
|
|
||||||
test(" hello world", "hello world");
|
|
||||||
test("hello world ", "hello world");
|
|
||||||
test(" hello world ", "hello world");
|
|
||||||
|
|
||||||
//one for goot luck
|
|
||||||
assert " hello world ".trim() == "hello world", "hello world.trim() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
//test trim custom values
|
|
||||||
{
|
|
||||||
var chars = "heliod";
|
|
||||||
|
|
||||||
assert "hello world".trim(chars) == " wor", "custom _trim() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
//test trimBegin() & trimEnd()
|
|
||||||
assert " foo ".trimBegin() == "foo ", "string.trimBegin() failed";
|
|
||||||
assert " foo ".trimEnd() == " foo", "string.trimBegin() failed";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
print "All good";
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
//test this logic for memory leaks
|
|
||||||
{
|
|
||||||
import compound;
|
|
||||||
import timer;
|
|
||||||
|
|
||||||
fn start(k, v) {
|
|
||||||
return startTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check(k, v) {
|
|
||||||
var l = v.stopTimer();
|
|
||||||
print l.timerToString();
|
|
||||||
l.destroyTimer();
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn destroy(k, v) {
|
|
||||||
v.destroyTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
var arr = [1];
|
|
||||||
|
|
||||||
arr
|
|
||||||
.map(start)
|
|
||||||
.map(check)
|
|
||||||
.map(check)
|
|
||||||
.map(check)
|
|
||||||
.map(check)
|
|
||||||
.map(check)
|
|
||||||
.map(check)
|
|
||||||
.map(check)
|
|
||||||
.map(check)
|
|
||||||
.map(check)
|
|
||||||
.map(check)
|
|
||||||
.map(destroy)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
print "All good";
|
|
||||||
|
|||||||
@@ -1,9 +1,323 @@
|
|||||||
//test the standard library
|
|
||||||
{
|
|
||||||
import standard;
|
import standard;
|
||||||
|
|
||||||
|
//test clock
|
||||||
|
{
|
||||||
//this depends on external factors, so only check the length
|
//this depends on external factors, so only check the length
|
||||||
assert clock().length() == 24, "clock() import failed";
|
assert clock().length() == 24, "clock().length() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test concat
|
||||||
|
{
|
||||||
|
//test array concat
|
||||||
|
{
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
var b = [4, 5, 6];
|
||||||
|
|
||||||
|
var c = a.concat(b).concat(b);
|
||||||
|
|
||||||
|
assert c == [1, 2, 3, 4, 5, 6, 4, 5, 6], "array.concat() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test dictionary concat
|
||||||
|
{
|
||||||
|
var a = ["one" : 1, "two": 2, "three": 3];
|
||||||
|
var b = ["four" : 4, "five": 5, "six": 6];
|
||||||
|
|
||||||
|
var c = a.concat(b);
|
||||||
|
|
||||||
|
assert c.length() == 6, "dictionary.concat().length() failed";
|
||||||
|
|
||||||
|
assert c == ["one" : 1, "two": 2, "three": 3, "four" : 4, "five": 5, "six": 6], "dictionary.concat() comparison failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test dictionary concat with clashing keys
|
||||||
|
{
|
||||||
|
var a = ["one" : 1, "two": 2, "three": 3, "random": 1];
|
||||||
|
var b = ["four" : 4, "five": 5, "six": 6, "random": 2];
|
||||||
|
|
||||||
|
var c = a.concat(b);
|
||||||
|
|
||||||
|
assert c["random"] == 1, "dictionary.concat() clashing keys failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test string concat
|
||||||
|
{
|
||||||
|
var a = "foo";
|
||||||
|
var b = "bar";
|
||||||
|
|
||||||
|
var c = a.concat(b);
|
||||||
|
|
||||||
|
assert c == "foobar", "string.concat() failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test containsKey
|
||||||
|
{
|
||||||
|
var d = ["one": 1, "two": 2];
|
||||||
|
|
||||||
|
assert d.containsKey("one") == true, "dictionary.containsKey() == true failed";
|
||||||
|
assert d.containsKey("three") == false, "dictionary.containsKey() == false failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test containsValue
|
||||||
|
{
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
var d = ["one": 1, "two": 2];
|
||||||
|
|
||||||
|
assert a.containsValue(1) == true, "array.containsValue() == true failed";
|
||||||
|
assert a.containsValue(5) == false, "array.containsValue() == false failed";
|
||||||
|
assert d.containsValue(1) == true, "dictionary.containsValue() == true failed";
|
||||||
|
assert d.containsValue(3) == false, "dictionary.containsValue() == false failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test every
|
||||||
|
{
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
var d = ["one": 1, "two": 2];
|
||||||
|
|
||||||
|
var counter = 0;
|
||||||
|
fn f(k, v) {
|
||||||
|
counter++;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert a.every(f) == true, "array.every() == true failed";
|
||||||
|
assert d.every(f) == true, "dictionary.every() == true failed";
|
||||||
|
|
||||||
|
assert counter == 5, "Unexpected number of calls for _every() == true";
|
||||||
|
|
||||||
|
counter = 0;
|
||||||
|
a[1] = false;
|
||||||
|
d["two"] = false;
|
||||||
|
|
||||||
|
assert a.every(f) == false, "array.every() == false failed";
|
||||||
|
assert d.every(f) == false, "dictionary.every() == false failed";
|
||||||
|
|
||||||
|
assert counter == 4, "Unexpected number of calls for _every() == false";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test filter
|
||||||
|
{
|
||||||
|
var a = [1, 2, 3, 4];
|
||||||
|
var d = ["one": 1, "two": 2, "three": 3, "four": 4];
|
||||||
|
|
||||||
|
fn f(k, v) {
|
||||||
|
return v % 2 == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert a.filter(f) == [2, 4], "array.filter() failed";
|
||||||
|
assert d.filter(f) == ["two": 2, "four": 4], "dictionary.filter() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test forEach
|
||||||
|
{
|
||||||
|
var counter = 0;
|
||||||
|
|
||||||
|
fn p(k, v) {
|
||||||
|
counter++;
|
||||||
|
print string k + ": " + string v;
|
||||||
|
}
|
||||||
|
|
||||||
|
var a = ["a", "b"];
|
||||||
|
var d = ["foo": 1, "bar": 2, "bazz": 3, "fizz": 4];
|
||||||
|
|
||||||
|
a.forEach(p);
|
||||||
|
assert counter == 2, "forEach ran an unusual number of times";
|
||||||
|
|
||||||
|
counter = 0;
|
||||||
|
d.forEach(p);
|
||||||
|
assert counter == 4, "forEach ran an unusual number of times";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test getKeys
|
||||||
|
{
|
||||||
|
var d = ["foo": 1, "bar": 2];
|
||||||
|
|
||||||
|
var a = d.getKeys();
|
||||||
|
|
||||||
|
assert a.length() == 2, "_getKeys() length failed";
|
||||||
|
|
||||||
|
//NOTE: dependant on hash algorithm
|
||||||
|
assert a == ["bar", "foo"], "_getKeys() result failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test getValues
|
||||||
|
{
|
||||||
|
var d = ["foo": 1, "bar": 2];
|
||||||
|
|
||||||
|
var a = d.getValues();
|
||||||
|
|
||||||
|
assert a.length() == 2, "_getValues() length failed";
|
||||||
|
|
||||||
|
//NOTE: dependant on hash algorithm
|
||||||
|
assert a == [2, 1], "_getValues() result failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test indexOf
|
||||||
|
{
|
||||||
|
var a = [1, 2, 42, 3];
|
||||||
|
|
||||||
|
//results are zero-indexed
|
||||||
|
assert a.indexOf(42) == 2, "_indexOf() failed";
|
||||||
|
assert a.indexOf(4) == null, "_indexOf() == null failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test map
|
||||||
|
{
|
||||||
|
//test map with toy functions
|
||||||
|
{
|
||||||
|
fn increment(k, v) {
|
||||||
|
return v + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
var d = ["four": 4, "five": 5, "six": 6];
|
||||||
|
|
||||||
|
assert a.map(increment).map(increment).map(increment) == [4,5,6], "array.map() failed";
|
||||||
|
assert d.map(increment).map(increment).map(increment) == [8,9,7], "dictionary.map() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test map with native functions
|
||||||
|
{
|
||||||
|
//TODO: write some native functions for use with map
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test reduce
|
||||||
|
{
|
||||||
|
var a = [1, 2, 3, 4];
|
||||||
|
var d = ["one": 1, "two": 2, "three": 3, "four": 4];
|
||||||
|
|
||||||
|
fn f(acc, k, v) {
|
||||||
|
return acc + v;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert a.reduce(0, f) == 10, "array.reduce() failed";
|
||||||
|
assert d.reduce(0, f) == 10, "dictionary.reduce() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test some
|
||||||
|
{
|
||||||
|
var a = [false, false, false];
|
||||||
|
var d = ["one": false, "two": false];
|
||||||
|
|
||||||
|
var counter = 0;
|
||||||
|
fn f(k, v) {
|
||||||
|
counter++;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert a.some(f) == false, "array.some() == false failed";
|
||||||
|
assert d.some(f) == false, "dictionary.some() == false failed";
|
||||||
|
|
||||||
|
assert counter == 5, "Unexpected number of calls for _some() == false";
|
||||||
|
|
||||||
|
counter = 0;
|
||||||
|
a[1] = true;
|
||||||
|
d["two"] = true;
|
||||||
|
|
||||||
|
assert a.some(f) == true, "array.some() == true failed";
|
||||||
|
assert d.some(f) == true, "dictionary.some() == true failed";
|
||||||
|
|
||||||
|
assert counter == 4, "Unexpected number of calls for _some() == true";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test sort
|
||||||
|
{
|
||||||
|
fn less(a, b) {
|
||||||
|
return a < b;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn greater(a, b) {
|
||||||
|
return a > b;
|
||||||
|
}
|
||||||
|
|
||||||
|
var a = [7, 2, 1, 8, 6, 3, 5, 4];
|
||||||
|
var b = [7, 2, 1, 4, 6, 3, 5, 8];
|
||||||
|
var c = [1, 2, 3, 4, 5, 6, 7, 8];
|
||||||
|
var d = [7, 2, 1, 8, 6, 3, 5, 4];
|
||||||
|
|
||||||
|
a = a.sort(less);
|
||||||
|
b = b.sort(less);
|
||||||
|
c = c.sort(less);
|
||||||
|
d = d.sort(greater);
|
||||||
|
|
||||||
|
assert a == [1, 2, 3, 4, 5, 6, 7, 8], "array.sort(less) failed";
|
||||||
|
assert b == [1, 2, 3, 4, 5, 6, 7, 8], "array.sort(less) with pivot high failed";
|
||||||
|
assert c == [1, 2, 3, 4, 5, 6, 7, 8], "array.sort(less) pre-sorted array failed";
|
||||||
|
assert d == [8, 7, 6, 5, 4, 3, 2, 1], "array.sort(greater) failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test toLower
|
||||||
|
{
|
||||||
|
assert "Hello World".toLower() == "hello world", "_toLower() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test toString
|
||||||
|
{
|
||||||
|
var a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
|
||||||
|
|
||||||
|
var s = a.toString();
|
||||||
|
|
||||||
|
assert s == "[[1,2,3],[4,5,6],[7,8,9]]", "array._toString() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test toUpper
|
||||||
|
{
|
||||||
|
assert "Hello World".toUpper() == "HELLO WORLD", "_toUpper() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//test trim defaults
|
||||||
|
{
|
||||||
|
{
|
||||||
|
//test a bunch
|
||||||
|
fn test(s, pass) {
|
||||||
|
var result = s.trim();
|
||||||
|
assert result == pass, "_trim(" + result + ") failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
test("hello world", "hello world");
|
||||||
|
test(" hello world", "hello world");
|
||||||
|
test("hello world ", "hello world");
|
||||||
|
test(" hello world ", "hello world");
|
||||||
|
test(" hello world", "hello world");
|
||||||
|
test("hello world ", "hello world");
|
||||||
|
test(" hello world ", "hello world");
|
||||||
|
test(" hello world", "hello world");
|
||||||
|
test("hello world ", "hello world");
|
||||||
|
test(" hello world ", "hello world");
|
||||||
|
|
||||||
|
//one for goot luck
|
||||||
|
assert " hello world ".trim() == "hello world", "hello world.trim() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test trim custom values
|
||||||
|
{
|
||||||
|
var chars = "heliod";
|
||||||
|
|
||||||
|
assert "hello world".trim(chars) == " wor", "custom _trim() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test trimBegin() & trimEnd()
|
||||||
|
assert " foo ".trimBegin() == "foo ", "string.trimBegin() failed";
|
||||||
|
assert " foo ".trimEnd() == " foo", "string.trimBegin() failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//polyfill the _insert function
|
||||||
|
fn _insert(self, k, v) {
|
||||||
|
var tmp1 = v;
|
||||||
|
var tmp2;
|
||||||
|
for (var i = k; i < self.length(); i++) {
|
||||||
|
tmp2 = self[i];
|
||||||
|
self[i] = tmp1;
|
||||||
|
tmp1 = tmp2;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.push(tmp1);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
|
||||||
|
a = a.insert(1, 42);
|
||||||
|
|
||||||
|
assert a == [1, 42, 2, 3], "polyfill insert failed";
|
||||||
|
|
||||||
|
|
||||||
|
print "All good";
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
//polyfill the remove function
|
||||||
|
fn _remove(self, k) {
|
||||||
|
var result = [];
|
||||||
|
|
||||||
|
for (var i = 0; i <= k - 1; i++) {
|
||||||
|
result.push( self[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = k + 1; i < self.length(); i++) {
|
||||||
|
result.push( self[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
|
||||||
|
assert a.remove(0) == [2, 3], "polyfill remove(start) failed";
|
||||||
|
assert a.remove(1) == [1, 3], "polyfill remove(middle) failed";
|
||||||
|
assert a.remove(2) == [1, 2], "polyfill remove(end) failed";
|
||||||
|
|
||||||
|
|
||||||
|
print "All good";
|
||||||
@@ -117,6 +117,8 @@ int main() {
|
|||||||
"dottify-bugfix.toy",
|
"dottify-bugfix.toy",
|
||||||
"functions.toy",
|
"functions.toy",
|
||||||
"index-arrays.toy",
|
"index-arrays.toy",
|
||||||
|
"index-assignment-both-bugfix.toy",
|
||||||
|
"index-assignment-left-bugfix.toy",
|
||||||
"index-dictionaries.toy",
|
"index-dictionaries.toy",
|
||||||
"index-strings.toy",
|
"index-strings.toy",
|
||||||
"jumps.toy",
|
"jumps.toy",
|
||||||
@@ -128,6 +130,8 @@ int main() {
|
|||||||
"native-functions.toy",
|
"native-functions.toy",
|
||||||
"or-chaining-bugfix.toy",
|
"or-chaining-bugfix.toy",
|
||||||
"panic-within-functions.toy",
|
"panic-within-functions.toy",
|
||||||
|
"polyfill-insert.toy",
|
||||||
|
"polyfill-remove.toy",
|
||||||
"ternary-expressions.toy",
|
"ternary-expressions.toy",
|
||||||
"types.toy",
|
"types.toy",
|
||||||
NULL
|
NULL
|
||||||
|
|||||||
@@ -14,10 +14,8 @@
|
|||||||
#include "../repl/repl_tools.h"
|
#include "../repl/repl_tools.h"
|
||||||
|
|
||||||
#include "../repl/lib_about.h"
|
#include "../repl/lib_about.h"
|
||||||
#include "../repl/lib_compound.h"
|
|
||||||
#include "../repl/lib_runner.h"
|
#include "../repl/lib_runner.h"
|
||||||
#include "../repl/lib_standard.h"
|
#include "../repl/lib_standard.h"
|
||||||
#include "../repl/lib_timer.h"
|
|
||||||
|
|
||||||
//supress the print output
|
//supress the print output
|
||||||
static void noPrintFn(const char* output) {
|
static void noPrintFn(const char* output) {
|
||||||
@@ -64,9 +62,7 @@ void runBinaryQuietly(const unsigned char* tb, size_t size) {
|
|||||||
|
|
||||||
//inject the libs
|
//inject the libs
|
||||||
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
||||||
Toy_injectNativeHook(&interpreter, "compound", Toy_hookCompound);
|
|
||||||
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
||||||
Toy_injectNativeHook(&interpreter, "timer", Toy_hookTimer);
|
|
||||||
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
||||||
|
|
||||||
Toy_runInterpreter(&interpreter, tb, size);
|
Toy_runInterpreter(&interpreter, tb, size);
|
||||||
@@ -96,10 +92,8 @@ int main() {
|
|||||||
Payload payloads[] = {
|
Payload payloads[] = {
|
||||||
{"interactions.toy", "standard", Toy_hookStandard}, //interactions needs standard
|
{"interactions.toy", "standard", Toy_hookStandard}, //interactions needs standard
|
||||||
{"about.toy", "about", Toy_hookAbout},
|
{"about.toy", "about", Toy_hookAbout},
|
||||||
{"compound.toy", "compound", Toy_hookCompound},
|
|
||||||
{"runner.toy", "runner", Toy_hookRunner},
|
|
||||||
{"standard.toy", "standard", Toy_hookStandard},
|
{"standard.toy", "standard", Toy_hookStandard},
|
||||||
{"timer.toy", "timer", Toy_hookTimer},
|
{"runner.toy", "runner", Toy_hookRunner},
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user