stripped a lot of files out
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
|||||||
[submodule "Toy"]
|
|
||||||
path = Toy
|
|
||||||
url = https://github.com/Ratstail91/Toy
|
|
||||||
58
Airport.sln
58
Airport.sln
@@ -1,58 +0,0 @@
|
|||||||
|
|
||||||
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}") = "Box", "Box.vcxproj", "{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{26360002-CC2A-469A-9B28-BA0C1AF41657} = {26360002-CC2A-469A-9B28-BA0C1AF41657}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Toy", "Toy\Toy.vcxproj", "{26360002-CC2A-469A-9B28-BA0C1AF41657}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Airport", "Airport.vcxproj", "{97F823E5-3AB8-47EF-B142-C15DD7CADF76}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{26360002-CC2A-469A-9B28-BA0C1AF41657} = {26360002-CC2A-469A-9B28-BA0C1AF41657}
|
|
||||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79} = {348A36D9-181E-46AD-BEEB-8A3FFAA50E79}
|
|
||||||
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
|
|
||||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Debug|x86.Build.0 = Debug|Win32
|
|
||||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Release|x64.Build.0 = Release|x64
|
|
||||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}.Release|x86.Build.0 = Release|Win32
|
|
||||||
{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 = {11A7E1C9-DA78-4754-9B70-3B328B0B5471}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
161
Airport.vcxproj
161
Airport.vcxproj
@@ -1,161 +0,0 @@
|
|||||||
<?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>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="source\main.c" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="assets\scripts\demo\scene.toy" />
|
|
||||||
<None Include="assets\scripts\demo\tilemap\layer-background.toy" />
|
|
||||||
<None Include="assets\scripts\demo\tilemap\layer-walls.toy" />
|
|
||||||
<None Include="assets\scripts\demo\tilemap\tilemap.toy" />
|
|
||||||
<None Include="assets\scripts\empty.toy" />
|
|
||||||
<None Include="assets\scripts\airplane.toy" />
|
|
||||||
<None Include="assets\scripts\gameplay\drone.toy" />
|
|
||||||
<None Include="assets\scripts\gameplay\lejana.toy" />
|
|
||||||
<None Include="assets\scripts\gameplay\scene.toy" />
|
|
||||||
<None Include="assets\scripts\gameplay\step-counter.toy" />
|
|
||||||
<None Include="assets\scripts\gameplay\text.toy" />
|
|
||||||
<None Include="assets\scripts\gameplay\tilemap.toy" />
|
|
||||||
<None Include="assets\scripts\init.toy" />
|
|
||||||
</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>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<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>SDL2main.lib;SDL2.lib;SDL2_image.lib;Toy.lib;Box.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
<AdditionalLibraryDirectories>$(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
</Link>
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>$(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;$(SolutionDir)box;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
|
||||||
<PreprocessorDefinitions>TOY_DISABLE_REPL</PreprocessorDefinitions>
|
|
||||||
</ClCompile>
|
|
||||||
<PreBuildEvent>
|
|
||||||
<Command>
|
|
||||||
</Command>
|
|
||||||
</PreBuildEvent>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
|
||||||
<PreprocessorDefinitions>TOY_DISABLE_REPL</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>$(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;$(SolutionDir)box;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<AdditionalLibraryDirectories>$(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;Toy.lib;Box.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
<PreBuildEvent>
|
|
||||||
<Command>
|
|
||||||
</Command>
|
|
||||||
</PreBuildEvent>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
170
Box.vcxproj
170
Box.vcxproj
@@ -1,170 +0,0 @@
|
|||||||
<?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>{348A36D9-181E-46AD-BEEB-8A3FFAA50E79}</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>DynamicLibrary</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>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<OutDir>$(SolutionDir)out\$(Configuration)\</OutDir>
|
|
||||||
<IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;BOX_EXPORTS;BOX_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;BOX_EXPORTS;BOX_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>
|
|
||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
|
||||||
<PreprocessorDefinitions>TOY_DISABLE_REPL;BOX_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>$(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<AdditionalLibraryDirectories>$(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<AdditionalDependencies>SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;Toy.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
<PreBuildEvent>
|
|
||||||
<Command>xcopy "$(SolutionDir)Toy\repl\lib*.*" "$(SolutionDir)box" /Y /I /E
|
|
||||||
xcopy "$(SolutionDir)Toy\repl\repl_tools.*" "$(SolutionDir)box" /Y /I /E</Command>
|
|
||||||
</PreBuildEvent>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
|
||||||
<ClCompile>
|
|
||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
|
||||||
<PreprocessorDefinitions>TOY_DISABLE_REPL;BOX_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>$(SDL2Dir)\include;$(SDL2ImageDir)\include;$(SDL2TTFDir)\include;%(SolutionDir)Toy\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<AdditionalLibraryDirectories>$(SDL2Dir)\lib\x64;$(SDL2ImageDir)\lib\x64;$(SDL2TTFDir)\lib\x64;$(SolutionDir)out\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
|
||||||
<AdditionalDependencies>SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;Toy.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
<PreBuildEvent>
|
|
||||||
<Command>xcopy "$(SolutionDir)Toy\repl\lib*.*" "$(SolutionDir)box" /Y /I /E
|
|
||||||
xcopy "$(SolutionDir)Toy\repl\repl_tools.*" "$(SolutionDir)box" /Y /I /E</Command>
|
|
||||||
</PreBuildEvent>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="box\box_common.c" />
|
|
||||||
<ClCompile Include="box\box_engine.c" />
|
|
||||||
<ClCompile Include="box\box_node.c" />
|
|
||||||
<ClCompile Include="box\dbg_profiler.c" />
|
|
||||||
<ClCompile Include="box\lib_about.c" />
|
|
||||||
<ClCompile Include="box\lib_engine.c" />
|
|
||||||
<ClCompile Include="box\lib_input.c" />
|
|
||||||
<ClCompile Include="box\lib_node.c" />
|
|
||||||
<ClCompile Include="box\lib_random.c" />
|
|
||||||
<ClCompile Include="box\lib_runner.c" />
|
|
||||||
<ClCompile Include="box\lib_standard.c" />
|
|
||||||
<ClCompile Include="box\repl_tools.c" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="box\box_common.h" />
|
|
||||||
<ClInclude Include="box\box_engine.h" />
|
|
||||||
<ClInclude Include="box\box_node.h" />
|
|
||||||
<ClInclude Include="box\dbg_profiler.h" />
|
|
||||||
<ClInclude Include="box\lib_about.h" />
|
|
||||||
<ClInclude Include="box\lib_engine.h" />
|
|
||||||
<ClInclude Include="box\lib_input.h" />
|
|
||||||
<ClInclude Include="box\lib_node.h" />
|
|
||||||
<ClInclude Include="box\lib_random.h" />
|
|
||||||
<ClInclude Include="box\lib_runner.h" />
|
|
||||||
<ClInclude Include="box\lib_standard.h" />
|
|
||||||
<ClInclude Include="box\repl_tools.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
||||||
20
README.md
20
README.md
@@ -2,27 +2,21 @@
|
|||||||
|
|
||||||
The best way to build a game engine, is to build a game first.
|
The best way to build a game engine, is to build a game first.
|
||||||
|
|
||||||
This project has now been adapted into a roguelike for the 7 day roguelike jam.
|
This game utilizes the [Box Game Engine](https://github.com/Ratstail91/Box) the [Toy Programming Language](https://toylang.com).
|
||||||
|
|
||||||
This game/engine utilizes the [Toy programming langauge](https://toylang.com).
|
# Cloning
|
||||||
|
|
||||||
## Cloning
|
|
||||||
|
|
||||||
Either clone recursively, or run `git submodule update --init` after cloning.
|
Either clone recursively, or run `git submodule update --init` after cloning.
|
||||||
|
|
||||||
## Building
|
# Building
|
||||||
|
|
||||||
We're now using Visual Studio - define the following environment variables to point to the root of each SDL2 lib:
|
WIP
|
||||||
|
|
||||||
* `SDL2Dir`
|
# Running
|
||||||
* `SDL2ImageDir`
|
|
||||||
* `SDL2TTFDir`
|
|
||||||
|
|
||||||
## Running
|
|
||||||
|
|
||||||
Make sure the program can see the `assets` folder (symbolic links can help), and all of the required DLLs are present.
|
Make sure the program can see the `assets` folder (symbolic links can help), and all of the required DLLs are present.
|
||||||
|
|
||||||
## Dependencies
|
# Dependencies
|
||||||
|
|
||||||
* SDL2
|
* SDL2
|
||||||
* SDL2_image
|
* SDL2_image
|
||||||
@@ -32,6 +26,6 @@ Make sure the program can see the `assets` folder (symbolic links can help), and
|
|||||||
|
|
||||||
* Art - Evan Hartshorn
|
* Art - Evan Hartshorn
|
||||||
* Coding - Kayne Ruse
|
* Coding - Kayne Ruse
|
||||||
* Font - Ancient God (Koczman B<>lint)
|
* Font - Ancient God (Koczman B<>lint)
|
||||||
* Font - AlphaBeta (Brian Kent)
|
* Font - AlphaBeta (Brian Kent)
|
||||||
|
|
||||||
|
|||||||
1
Toy
1
Toy
Submodule Toy deleted from 0e41b00ef4
@@ -1,10 +0,0 @@
|
|||||||
#include "box_common.h"
|
|
||||||
|
|
||||||
STATIC_ASSERT(sizeof(char) == 1);
|
|
||||||
STATIC_ASSERT(sizeof(short) == 2);
|
|
||||||
STATIC_ASSERT(sizeof(int) == 4);
|
|
||||||
STATIC_ASSERT(sizeof(float) == 4);
|
|
||||||
STATIC_ASSERT(sizeof(unsigned char) == 1);
|
|
||||||
STATIC_ASSERT(sizeof(unsigned short) == 2);
|
|
||||||
STATIC_ASSERT(sizeof(unsigned int) == 4);
|
|
||||||
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define BOX_VERSION_MAJOR 0
|
|
||||||
#define BOX_VERSION_MINOR 1
|
|
||||||
#define BOX_VERSION_PATCH 0
|
|
||||||
#define BOX_VERSION_BUILD __DATE__ " " __TIME__
|
|
||||||
|
|
||||||
//platform/compiler-specific instructions
|
|
||||||
#if defined(__linux__) || defined(__MINGW32__) || defined(__GNUC__)
|
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
#include <SDL2/SDL_image.h>
|
|
||||||
#include <SDL2/SDL_ttf.h>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#define BOX_API extern
|
|
||||||
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
#include <SDL_image.h>
|
|
||||||
#include <SDL_ttf.h>
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <crtdbg.h>
|
|
||||||
|
|
||||||
#ifndef BOX_EXPORT
|
|
||||||
#define BOX_API __declspec(dllimport)
|
|
||||||
#else
|
|
||||||
#define BOX_API __declspec(dllexport)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//TODO: figure out the sleep issue
|
|
||||||
#define sleep Sleep
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define BOX_API extern
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
//test variable sizes based on platform
|
|
||||||
#define STATIC_ASSERT(test_for_true) static_assert((test_for_true), "(" #test_for_true ") failed")
|
|
||||||
|
|
||||||
//debugging
|
|
||||||
#include "dbg_profiler.h"
|
|
||||||
482
box/box_engine.c
482
box/box_engine.c
@@ -1,482 +0,0 @@
|
|||||||
#include "box_engine.h"
|
|
||||||
|
|
||||||
#include "lib_about.h"
|
|
||||||
#include "lib_standard.h"
|
|
||||||
#include "lib_random.h"
|
|
||||||
#include "lib_runner.h"
|
|
||||||
#include "lib_engine.h"
|
|
||||||
#include "lib_node.h"
|
|
||||||
#include "lib_input.h"
|
|
||||||
|
|
||||||
#include "repl_tools.h"
|
|
||||||
|
|
||||||
#include "toy_memory.h"
|
|
||||||
#include "toy_lexer.h"
|
|
||||||
#include "toy_parser.h"
|
|
||||||
#include "toy_compiler.h"
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
#include "toy_literal_array.h"
|
|
||||||
#include "toy_literal_dictionary.h"
|
|
||||||
|
|
||||||
#include "toy_console_colors.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
//define the extern engine object
|
|
||||||
Box_Engine engine;
|
|
||||||
|
|
||||||
//errors here should be fatal
|
|
||||||
static void fatalError(char* message) {
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "%s" TOY_CC_RESET, message);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//exposed functions
|
|
||||||
void Box_initEngine() {
|
|
||||||
//clear
|
|
||||||
engine.rootNode = NULL;
|
|
||||||
engine.nextRootNodeFilename = TOY_TO_NULL_LITERAL;
|
|
||||||
engine.running = false;
|
|
||||||
engine.window = NULL;
|
|
||||||
engine.renderer = NULL;
|
|
||||||
|
|
||||||
//init SDL
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
|
||||||
fatalError("Failed to initialize SDL2");
|
|
||||||
}
|
|
||||||
|
|
||||||
//init SDL_image
|
|
||||||
int imageFlags = IMG_INIT_PNG | IMG_INIT_JPG;
|
|
||||||
if (IMG_Init(imageFlags) != imageFlags) {
|
|
||||||
fatalError("Failed to initialize SDL2_image");
|
|
||||||
}
|
|
||||||
|
|
||||||
//init SDL_ttf
|
|
||||||
if (TTF_Init() == -1) {
|
|
||||||
fatalError("Failed to initialize SDL2_ttf");
|
|
||||||
}
|
|
||||||
|
|
||||||
//init events
|
|
||||||
Toy_initLiteralDictionary(&engine.symKeyDownEvents);
|
|
||||||
Toy_initLiteralDictionary(&engine.symKeyUpEvents);
|
|
||||||
|
|
||||||
//init Toy
|
|
||||||
Toy_initInterpreter(&engine.interpreter);
|
|
||||||
Toy_injectNativeHook(&engine.interpreter, "about", Toy_hookAbout);
|
|
||||||
Toy_injectNativeHook(&engine.interpreter, "standard", Toy_hookStandard);
|
|
||||||
Toy_injectNativeHook(&engine.interpreter, "random", Toy_hookRandom);
|
|
||||||
Toy_injectNativeHook(&engine.interpreter, "runner", Toy_hookRunner);
|
|
||||||
Toy_injectNativeHook(&engine.interpreter, "engine", Box_hookEngine);
|
|
||||||
Toy_injectNativeHook(&engine.interpreter, "node", Box_hookNode);
|
|
||||||
Toy_injectNativeHook(&engine.interpreter, "input", Box_hookInput);
|
|
||||||
|
|
||||||
//run the init
|
|
||||||
size_t size = 0;
|
|
||||||
const unsigned char* source = Toy_readFile("./assets/scripts/init.toy", &size);
|
|
||||||
|
|
||||||
if (!source) {
|
|
||||||
fatalError("Couldn't read /assets/scripts/init.toy");
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned char* tb = Toy_compileString((const char*)source, &size);
|
|
||||||
free((void*)source);
|
|
||||||
|
|
||||||
//A quirk of the setup is that anything defined in `init.toy` becomes a global object
|
|
||||||
Toy_runInterpreter(&engine.interpreter, tb, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box_freeEngine() {
|
|
||||||
//clear existing root node
|
|
||||||
if (engine.rootNode != NULL) {
|
|
||||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onFree", NULL);
|
|
||||||
Box_freeNode(engine.rootNode);
|
|
||||||
engine.rootNode = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TOY_IS_NULL(engine.nextRootNodeFilename)) {
|
|
||||||
Toy_freeLiteral(engine.nextRootNodeFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_freeInterpreter(&engine.interpreter);
|
|
||||||
|
|
||||||
//free events
|
|
||||||
Toy_freeLiteralDictionary(&engine.symKeyDownEvents);
|
|
||||||
Toy_freeLiteralDictionary(&engine.symKeyUpEvents);
|
|
||||||
|
|
||||||
//free SDL
|
|
||||||
SDL_DestroyRenderer(engine.renderer);
|
|
||||||
SDL_DestroyWindow(engine.window);
|
|
||||||
SDL_Quit();
|
|
||||||
|
|
||||||
engine.renderer = NULL;
|
|
||||||
engine.window = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void execLoadRootNode() {
|
|
||||||
//if a new root node is NOT needed, skip out
|
|
||||||
if (TOY_IS_NULL(engine.nextRootNodeFilename)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//free the existing root node
|
|
||||||
if (engine.rootNode != NULL) {
|
|
||||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onFree", NULL);
|
|
||||||
Box_freeNode(engine.rootNode);
|
|
||||||
engine.rootNode = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//compile the new root node
|
|
||||||
size_t size = 0;
|
|
||||||
const unsigned char* source = Toy_readFile(Toy_toCString(TOY_AS_STRING(engine.nextRootNodeFilename)), &size);
|
|
||||||
const unsigned char* tb = Toy_compileString((const char*)source, &size);
|
|
||||||
free((void*)source);
|
|
||||||
|
|
||||||
//allocate the new root node
|
|
||||||
engine.rootNode = TOY_ALLOCATE(Box_Node, 1);
|
|
||||||
|
|
||||||
//BUGFIX: make an inner-interpreter
|
|
||||||
Toy_Interpreter inner;
|
|
||||||
|
|
||||||
//init the inner interpreter manually
|
|
||||||
Toy_initLiteralArray(&inner.literalCache);
|
|
||||||
inner.scope = Toy_pushScope(engine.interpreter.scope);
|
|
||||||
inner.bytecode = tb;
|
|
||||||
inner.length = size;
|
|
||||||
inner.count = 0;
|
|
||||||
inner.codeStart = -1;
|
|
||||||
inner.depth = engine.interpreter.depth + 1;
|
|
||||||
inner.panic = false;
|
|
||||||
Toy_initLiteralArray(&inner.stack);
|
|
||||||
inner.hooks = engine.interpreter.hooks;
|
|
||||||
Toy_setInterpreterPrint(&inner, engine.interpreter.printOutput);
|
|
||||||
Toy_setInterpreterAssert(&inner, engine.interpreter.assertOutput);
|
|
||||||
Toy_setInterpreterError(&inner, engine.interpreter.errorOutput);
|
|
||||||
|
|
||||||
Box_initNode(engine.rootNode, &inner, tb, size);
|
|
||||||
|
|
||||||
//immediately call onLoad() after running the script - for loading other nodes
|
|
||||||
Box_callNode(engine.rootNode, &inner, "onLoad", NULL);
|
|
||||||
|
|
||||||
//cache the scope for later freeing
|
|
||||||
engine.rootNode->scope = inner.scope;
|
|
||||||
|
|
||||||
//manual cleanup
|
|
||||||
Toy_freeLiteralArray(&inner.stack);
|
|
||||||
Toy_freeLiteralArray(&inner.literalCache);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(engine.nextRootNodeFilename);
|
|
||||||
engine.nextRootNodeFilename = TOY_TO_NULL_LITERAL;
|
|
||||||
|
|
||||||
//init the new node-tree
|
|
||||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onInit", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void execEvents() {
|
|
||||||
Toy_LiteralArray args; //save some allocation by reusing this
|
|
||||||
Toy_initLiteralArray(&args);
|
|
||||||
|
|
||||||
//poll all events
|
|
||||||
SDL_Event event;
|
|
||||||
|
|
||||||
while (SDL_PollEvent(&event)) {
|
|
||||||
switch(event.type) {
|
|
||||||
//quit
|
|
||||||
case SDL_QUIT: {
|
|
||||||
engine.running = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
//window events are handled internally
|
|
||||||
case SDL_WINDOWEVENT: {
|
|
||||||
switch(event.window.event) {
|
|
||||||
case SDL_WINDOWEVENT_RESIZED:
|
|
||||||
//TODO: toy onWindowResized, setLogicalWindowSize, getLogicalWindowSize
|
|
||||||
//engine.screenWidth = event.window.data1;
|
|
||||||
//engine.screenHeight = event.window.data2;
|
|
||||||
//SDL_RenderSetLogicalSize(engine.renderer, engine.screenWidth, engine.screenHeight);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
//input
|
|
||||||
case SDL_KEYDOWN: {
|
|
||||||
//bugfix: ignore repeat messages
|
|
||||||
if (event.key.repeat) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//determine the given keycode
|
|
||||||
Toy_Literal keycodeLiteral = TOY_TO_INTEGER_LITERAL( (int)(event.key.keysym.sym) );
|
|
||||||
if (!Toy_existsLiteralDictionary(&engine.symKeyDownEvents, keycodeLiteral)) {
|
|
||||||
Toy_freeLiteral(keycodeLiteral);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the event name
|
|
||||||
Toy_Literal eventLiteral = Toy_getLiteralDictionary(&engine.symKeyDownEvents, keycodeLiteral);
|
|
||||||
|
|
||||||
//call the function
|
|
||||||
Toy_pushLiteralArray(&args, eventLiteral);
|
|
||||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onKeyDown", &args);
|
|
||||||
Toy_freeLiteral(Toy_popLiteralArray(&args));
|
|
||||||
|
|
||||||
//push to the event list
|
|
||||||
Toy_freeLiteral(eventLiteral);
|
|
||||||
Toy_freeLiteral(keycodeLiteral);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_KEYUP: {
|
|
||||||
//bugfix: ignore repeat messages
|
|
||||||
if (event.key.repeat) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//determine the given keycode
|
|
||||||
Toy_Literal keycodeLiteral = TOY_TO_INTEGER_LITERAL( (int)(event.key.keysym.sym) );
|
|
||||||
if (!Toy_existsLiteralDictionary(&engine.symKeyUpEvents, keycodeLiteral)) {
|
|
||||||
Toy_freeLiteral(keycodeLiteral);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the event name
|
|
||||||
Toy_Literal eventLiteral = Toy_getLiteralDictionary(&engine.symKeyUpEvents, keycodeLiteral);
|
|
||||||
|
|
||||||
//call the function
|
|
||||||
Toy_pushLiteralArray(&args, eventLiteral);
|
|
||||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onKeyUp", &args);
|
|
||||||
Toy_freeLiteral(Toy_popLiteralArray(&args));
|
|
||||||
|
|
||||||
//push to the event list
|
|
||||||
Toy_freeLiteral(eventLiteral);
|
|
||||||
Toy_freeLiteral(keycodeLiteral);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
//mouse motion
|
|
||||||
case SDL_MOUSEMOTION: {
|
|
||||||
Toy_Literal mouseX = TOY_TO_INTEGER_LITERAL( (int)(event.motion.x) );
|
|
||||||
Toy_Literal mouseY = TOY_TO_INTEGER_LITERAL( (int)(event.motion.y) );
|
|
||||||
Toy_Literal mouseXRel = TOY_TO_INTEGER_LITERAL( (int)(event.motion.xrel) );
|
|
||||||
Toy_Literal mouseYRel = TOY_TO_INTEGER_LITERAL( (int)(event.motion.yrel) );
|
|
||||||
|
|
||||||
Toy_pushLiteralArray(&args, mouseX);
|
|
||||||
Toy_pushLiteralArray(&args, mouseY);
|
|
||||||
Toy_pushLiteralArray(&args, mouseXRel);
|
|
||||||
Toy_pushLiteralArray(&args, mouseYRel);
|
|
||||||
|
|
||||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onMouseMotion", &args);
|
|
||||||
|
|
||||||
Toy_freeLiteral(mouseX);
|
|
||||||
Toy_freeLiteral(mouseY);
|
|
||||||
Toy_freeLiteral(mouseXRel);
|
|
||||||
Toy_freeLiteral(mouseYRel);
|
|
||||||
|
|
||||||
//hack: manual free
|
|
||||||
for(int i = 0; i < args.count; i++) {
|
|
||||||
Toy_freeLiteral(args.literals[i]);
|
|
||||||
}
|
|
||||||
args.count = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
//mouse button down
|
|
||||||
case SDL_MOUSEBUTTONDOWN: {
|
|
||||||
Toy_Literal mouseX = TOY_TO_INTEGER_LITERAL( (int)(event.button.x) );
|
|
||||||
Toy_Literal mouseY = TOY_TO_INTEGER_LITERAL( (int)(event.button.y) );
|
|
||||||
Toy_Literal mouseButton;
|
|
||||||
|
|
||||||
switch (event.button.button) {
|
|
||||||
case SDL_BUTTON_LEFT:
|
|
||||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("left"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_BUTTON_MIDDLE:
|
|
||||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("middle"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_BUTTON_RIGHT:
|
|
||||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("right"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_BUTTON_X1:
|
|
||||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("x1"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_BUTTON_X2:
|
|
||||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("x2"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("unknown"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_pushLiteralArray(&args, mouseX);
|
|
||||||
Toy_pushLiteralArray(&args, mouseY);
|
|
||||||
Toy_pushLiteralArray(&args, mouseButton);
|
|
||||||
|
|
||||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onMouseButtonDown", &args);
|
|
||||||
|
|
||||||
Toy_freeLiteral(mouseX);
|
|
||||||
Toy_freeLiteral(mouseY);
|
|
||||||
Toy_freeLiteral(mouseButton);
|
|
||||||
|
|
||||||
//hack: manual free
|
|
||||||
for(int i = 0; i < args.count; i++) {
|
|
||||||
Toy_freeLiteral(args.literals[i]);
|
|
||||||
}
|
|
||||||
args.count = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
//mouse button up
|
|
||||||
case SDL_MOUSEBUTTONUP: {
|
|
||||||
Toy_Literal mouseX = TOY_TO_INTEGER_LITERAL( (int)(event.button.x) );
|
|
||||||
Toy_Literal mouseY = TOY_TO_INTEGER_LITERAL( (int)(event.button.y) );
|
|
||||||
Toy_Literal mouseButton;
|
|
||||||
|
|
||||||
switch (event.button.button) {
|
|
||||||
case SDL_BUTTON_LEFT:
|
|
||||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("left"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_BUTTON_MIDDLE:
|
|
||||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("middle"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_BUTTON_RIGHT:
|
|
||||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("right"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_BUTTON_X1:
|
|
||||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("x1"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_BUTTON_X2:
|
|
||||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("x2"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
mouseButton = TOY_TO_STRING_LITERAL(Toy_createRefString("unknown"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_pushLiteralArray(&args, mouseX);
|
|
||||||
Toy_pushLiteralArray(&args, mouseY);
|
|
||||||
Toy_pushLiteralArray(&args, mouseButton);
|
|
||||||
|
|
||||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onMouseButtonUp", &args);
|
|
||||||
|
|
||||||
Toy_freeLiteral(mouseX);
|
|
||||||
Toy_freeLiteral(mouseY);
|
|
||||||
Toy_freeLiteral(mouseButton);
|
|
||||||
|
|
||||||
//hack: manual free
|
|
||||||
for(int i = 0; i < args.count; i++) {
|
|
||||||
Toy_freeLiteral(args.literals[i]);
|
|
||||||
}
|
|
||||||
args.count = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
//mouse wheel
|
|
||||||
case SDL_MOUSEWHEEL: {
|
|
||||||
Toy_Literal mouseX = TOY_TO_INTEGER_LITERAL( (int)(event.wheel.x) );
|
|
||||||
Toy_Literal mouseY = TOY_TO_INTEGER_LITERAL( (int)(event.wheel.y) );
|
|
||||||
Toy_pushLiteralArray(&args, mouseX);
|
|
||||||
Toy_pushLiteralArray(&args, mouseY);
|
|
||||||
|
|
||||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onMouseWheel", &args);
|
|
||||||
|
|
||||||
Toy_freeLiteral(mouseX);
|
|
||||||
Toy_freeLiteral(mouseY);
|
|
||||||
|
|
||||||
//hack: manual free
|
|
||||||
for(int i = 0; i < args.count; i++) {
|
|
||||||
Toy_freeLiteral(args.literals[i]);
|
|
||||||
}
|
|
||||||
args.count = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_freeLiteralArray(&args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void execStep() {
|
|
||||||
if (engine.rootNode != NULL) {
|
|
||||||
//steps
|
|
||||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onStep", NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//the heart of the engine
|
|
||||||
void Box_execEngine() {
|
|
||||||
if (!engine.running) {
|
|
||||||
fatalError("Can't execute the engine (did you forget to initialize the screen?)");
|
|
||||||
}
|
|
||||||
|
|
||||||
//set up time
|
|
||||||
engine.realTime = clock();
|
|
||||||
engine.simTime = engine.realTime;
|
|
||||||
clock_t delta = (double) CLOCKS_PER_SEC / 30.0;
|
|
||||||
|
|
||||||
Dbg_Timer dbgTimer;
|
|
||||||
Dbg_FPSCounter fps;
|
|
||||||
|
|
||||||
Dbg_initTimer(&dbgTimer);
|
|
||||||
Dbg_initFPSCounter(&fps);
|
|
||||||
|
|
||||||
while (engine.running) {
|
|
||||||
Dbg_tickFPSCounter(&fps);
|
|
||||||
|
|
||||||
Dbg_clearConsole();
|
|
||||||
Dbg_printTimerLog(&dbgTimer);
|
|
||||||
Dbg_printFPSCounter(&fps);
|
|
||||||
|
|
||||||
Dbg_startTimer(&dbgTimer, "execLoadRootNode()");
|
|
||||||
execLoadRootNode();
|
|
||||||
Dbg_stopTimer(&dbgTimer);
|
|
||||||
|
|
||||||
Dbg_startTimer(&dbgTimer, "execEvents()");
|
|
||||||
execEvents();
|
|
||||||
Dbg_stopTimer(&dbgTimer);
|
|
||||||
|
|
||||||
//calc the time passed
|
|
||||||
engine.realTime = clock();
|
|
||||||
|
|
||||||
Dbg_startTimer(&dbgTimer, "execStep() (variable)");
|
|
||||||
//while not enough time has passed
|
|
||||||
while(engine.simTime < engine.realTime) {
|
|
||||||
//simulate the world
|
|
||||||
execStep();
|
|
||||||
|
|
||||||
//calc the time simulation
|
|
||||||
engine.simTime += delta;
|
|
||||||
}
|
|
||||||
Dbg_stopTimer(&dbgTimer);
|
|
||||||
|
|
||||||
//render the world
|
|
||||||
Dbg_startTimer(&dbgTimer, "clear screen");
|
|
||||||
SDL_SetRenderDrawColor(engine.renderer, 128, 128, 128, 255); //NOTE: This line can be disabled later
|
|
||||||
SDL_RenderClear(engine.renderer); //NOTE: This line can be disabled later
|
|
||||||
Dbg_stopTimer(&dbgTimer);
|
|
||||||
|
|
||||||
Dbg_startTimer(&dbgTimer, "onDraw() calls");
|
|
||||||
Box_callRecursiveNode(engine.rootNode, &engine.interpreter, "onDraw", NULL);
|
|
||||||
Dbg_stopTimer(&dbgTimer);
|
|
||||||
|
|
||||||
Dbg_startTimer(&dbgTimer, "render screen");
|
|
||||||
SDL_RenderPresent(engine.renderer);
|
|
||||||
Dbg_stopTimer(&dbgTimer);
|
|
||||||
}
|
|
||||||
|
|
||||||
Dbg_freeTimer(&dbgTimer);
|
|
||||||
Dbg_freeFPSCounter(&fps);
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "box_common.h"
|
|
||||||
#include "box_node.h"
|
|
||||||
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
#include "toy_literal_array.h"
|
|
||||||
#include "toy_literal_dictionary.h"
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
//the base engine object, which represents the state of the game
|
|
||||||
typedef struct Box_private_engine {
|
|
||||||
//engine stuff
|
|
||||||
Box_Node* rootNode;
|
|
||||||
Toy_Literal nextRootNodeFilename;
|
|
||||||
clock_t simTime;
|
|
||||||
clock_t realTime;
|
|
||||||
bool running;
|
|
||||||
|
|
||||||
//Toy stuff
|
|
||||||
Toy_Interpreter interpreter;
|
|
||||||
|
|
||||||
//SDL stuff
|
|
||||||
SDL_Window* window;
|
|
||||||
SDL_Renderer* renderer;
|
|
||||||
int screenWidth;
|
|
||||||
int screenHeight;
|
|
||||||
|
|
||||||
//input syms mapped to events
|
|
||||||
Toy_LiteralDictionary symKeyDownEvents; //keysym -> event names
|
|
||||||
Toy_LiteralDictionary symKeyUpEvents; //keysym -> event names
|
|
||||||
} Box_Engine;
|
|
||||||
|
|
||||||
//extern singleton - used by various libraries
|
|
||||||
extern Box_Engine engine;
|
|
||||||
|
|
||||||
//APIs for running the engine in main()
|
|
||||||
BOX_API void Box_initEngine();
|
|
||||||
BOX_API void Box_execEngine();
|
|
||||||
BOX_API void Box_freeEngine();
|
|
||||||
|
|
||||||
395
box/box_node.c
395
box/box_node.c
@@ -1,395 +0,0 @@
|
|||||||
#include "box_node.h"
|
|
||||||
#include "box_engine.h"
|
|
||||||
|
|
||||||
#include "toy_memory.h"
|
|
||||||
|
|
||||||
void Box_initNode(Box_Node* node, Toy_Interpreter* interpreter, const unsigned char* tb, size_t size) {
|
|
||||||
//init
|
|
||||||
// node->freeMemory = freeMemory;
|
|
||||||
node->functions = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
|
||||||
node->parent = NULL;
|
|
||||||
node->scope = NULL;
|
|
||||||
node->tag = OPAQUE_TAG_NODE;
|
|
||||||
node->children = NULL;
|
|
||||||
node->capacity = 0;
|
|
||||||
node->count = 0;
|
|
||||||
node->childCount = 0;
|
|
||||||
node->texture = NULL;
|
|
||||||
node->rect = ((SDL_Rect) { 0, 0, 0, 0 });
|
|
||||||
node->frames = 0;
|
|
||||||
|
|
||||||
Toy_initLiteralDictionary(node->functions);
|
|
||||||
|
|
||||||
//run bytecode
|
|
||||||
Toy_runInterpreter(interpreter, tb, size);
|
|
||||||
|
|
||||||
//grab all top-level functions from the dirty interpreter
|
|
||||||
Toy_LiteralDictionary* variablesPtr = &interpreter->scope->variables;
|
|
||||||
|
|
||||||
for (int i = 0; i < variablesPtr->capacity; i++) {
|
|
||||||
//skip empties and tombstones
|
|
||||||
if (TOY_IS_NULL(variablesPtr->entries[i].key)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if this variable is a function (this outmodes import and export)
|
|
||||||
Toy_private_dictionary_entry* entry = &variablesPtr->entries[i];
|
|
||||||
if (TOY_IS_FUNCTION(entry->value)) {
|
|
||||||
//save a copy
|
|
||||||
Toy_setLiteralDictionary(node->functions, entry->key, entry->value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box_pushNode(Box_Node* node, Box_Node* child) {
|
|
||||||
//push to the array
|
|
||||||
if (node->count + 1 > node->capacity) {
|
|
||||||
int oldCapacity = node->capacity;
|
|
||||||
|
|
||||||
node->capacity = TOY_GROW_CAPACITY(oldCapacity);
|
|
||||||
node->children = TOY_GROW_ARRAY(Box_Node*, node->children, oldCapacity, node->capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
//assign
|
|
||||||
node->children[node->count++] = child;
|
|
||||||
|
|
||||||
//reverse-assign
|
|
||||||
child->parent = node;
|
|
||||||
|
|
||||||
//count
|
|
||||||
node->childCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box_freeNode(Box_Node* node) {
|
|
||||||
if (node == NULL) {
|
|
||||||
return; //NO-OP
|
|
||||||
}
|
|
||||||
|
|
||||||
//free this node's children
|
|
||||||
for (int i = 0; i < node->count; i++) {
|
|
||||||
Box_freeNode(node->children[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//free the pointer array to the children
|
|
||||||
TOY_FREE_ARRAY(Box_Node*, node->children, node->capacity);
|
|
||||||
|
|
||||||
if (node->functions != NULL) {
|
|
||||||
Toy_freeLiteralDictionary(node->functions);
|
|
||||||
TOY_FREE(Toy_LiteralDictionary, node->functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node->scope != NULL) {
|
|
||||||
Toy_popScope(node->scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node->texture != NULL) {
|
|
||||||
Box_freeTextureNode(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
//free this node's memory
|
|
||||||
TOY_FREE(Box_Node, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
Box_Node* Box_getChildNode(Box_Node* node, int index) {
|
|
||||||
if (index < 0 || index > node->count) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return node->children[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box_freeChildNode(Box_Node* node, int index) {
|
|
||||||
//get the child node
|
|
||||||
Box_Node* childNode = node->children[index];
|
|
||||||
|
|
||||||
//free the node
|
|
||||||
if (childNode != NULL) {
|
|
||||||
Box_freeNode(childNode);
|
|
||||||
node->childCount--;
|
|
||||||
}
|
|
||||||
|
|
||||||
node->children[index] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void swapUtil(Box_Node** lhs, Box_Node** rhs) {
|
|
||||||
Box_Node* tmp = *lhs;
|
|
||||||
*lhs = *rhs;
|
|
||||||
*rhs = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
//copied from lib_standard.c
|
|
||||||
static void recursiveLiteralQuicksortUtil(Toy_Interpreter* interpreter, Box_Node** ptr, int count, Toy_Literal fnCompare) {
|
|
||||||
//base case
|
|
||||||
if (count <= 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int runner = 0;
|
|
||||||
|
|
||||||
//iterate through the array
|
|
||||||
for (int checker = 0; checker < count - 1; checker++) {
|
|
||||||
//if node is null, it is always "sorted" to the end
|
|
||||||
while (ptr[checker] == NULL && count > 0) {
|
|
||||||
swapUtil(&ptr[checker], &ptr[count - 1]);
|
|
||||||
count--;
|
|
||||||
}
|
|
||||||
|
|
||||||
//base case
|
|
||||||
if (count < 2) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_LiteralArray arguments;
|
|
||||||
Toy_LiteralArray returns;
|
|
||||||
|
|
||||||
Toy_initLiteralArray(&arguments);
|
|
||||||
Toy_initLiteralArray(&returns);
|
|
||||||
|
|
||||||
Toy_pushLiteralArray(&arguments, TOY_TO_OPAQUE_LITERAL(ptr[checker], OPAQUE_TAG_NODE));
|
|
||||||
Toy_pushLiteralArray(&arguments, TOY_TO_OPAQUE_LITERAL(ptr[count - 1], OPAQUE_TAG_NODE));
|
|
||||||
|
|
||||||
Toy_callLiteralFn(interpreter, fnCompare, &arguments, &returns);
|
|
||||||
|
|
||||||
Toy_Literal lessThan = Toy_popLiteralArray(&returns);
|
|
||||||
|
|
||||||
Toy_freeLiteralArray(&arguments);
|
|
||||||
Toy_freeLiteralArray(&returns);
|
|
||||||
|
|
||||||
if (TOY_IS_TRUTHY(lessThan)) {
|
|
||||||
swapUtil(&ptr[runner++], &ptr[checker]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_freeLiteral(lessThan);
|
|
||||||
}
|
|
||||||
|
|
||||||
//"shift everything up" so the pivot is in the middle
|
|
||||||
swapUtil(&ptr[runner], &ptr[count - 1]);
|
|
||||||
|
|
||||||
//recurse on each end
|
|
||||||
recursiveLiteralQuicksortUtil(interpreter, &ptr[0], runner, fnCompare);
|
|
||||||
recursiveLiteralQuicksortUtil(interpreter, &ptr[runner + 1], count - runner - 1, fnCompare);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOX_API void Box_sortChildrenNode(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal fnCompare) {
|
|
||||||
//check that this node's children aren't already sorted
|
|
||||||
bool sorted = true;
|
|
||||||
for (int checker = 0; checker < node->count - 1 && sorted; checker++) {
|
|
||||||
//NULL (tombstone) is always considered unsorted
|
|
||||||
if (node->children[checker] == NULL || node->children[checker + 1] == NULL) {
|
|
||||||
sorted = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_LiteralArray arguments;
|
|
||||||
Toy_LiteralArray returns;
|
|
||||||
|
|
||||||
Toy_initLiteralArray(&arguments);
|
|
||||||
Toy_initLiteralArray(&returns);
|
|
||||||
|
|
||||||
Toy_pushLiteralArray(&arguments, TOY_TO_OPAQUE_LITERAL(node->children[checker], OPAQUE_TAG_NODE));
|
|
||||||
Toy_pushLiteralArray(&arguments, TOY_TO_OPAQUE_LITERAL(node->children[checker + 1], OPAQUE_TAG_NODE));
|
|
||||||
|
|
||||||
Toy_callLiteralFn(interpreter, fnCompare, &arguments, &returns);
|
|
||||||
|
|
||||||
Toy_Literal lessThan = Toy_popLiteralArray(&returns);
|
|
||||||
|
|
||||||
Toy_freeLiteralArray(&arguments);
|
|
||||||
Toy_freeLiteralArray(&returns);
|
|
||||||
|
|
||||||
if (!TOY_IS_TRUTHY(lessThan)) {
|
|
||||||
sorted = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_freeLiteral(lessThan);
|
|
||||||
}
|
|
||||||
|
|
||||||
//sort the children
|
|
||||||
if (!sorted) {
|
|
||||||
recursiveLiteralQuicksortUtil(interpreter, node->children, node->count, fnCompare);
|
|
||||||
}
|
|
||||||
|
|
||||||
//re-count the newly-sorted children
|
|
||||||
for (int i = node->count - 1; node->children[i] == NULL; i--) {
|
|
||||||
node->count--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal Box_callNodeLiteral(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args) {
|
|
||||||
Toy_Literal ret = TOY_TO_NULL_LITERAL;
|
|
||||||
|
|
||||||
//if this fn exists
|
|
||||||
if (Toy_existsLiteralDictionary(node->functions, key)) {
|
|
||||||
Toy_Literal fn = Toy_getLiteralDictionary(node->functions, key);
|
|
||||||
Toy_Literal n = TOY_TO_OPAQUE_LITERAL(node, node->tag);
|
|
||||||
|
|
||||||
Toy_LiteralArray arguments;
|
|
||||||
Toy_LiteralArray returns;
|
|
||||||
Toy_initLiteralArray(&arguments);
|
|
||||||
Toy_initLiteralArray(&returns);
|
|
||||||
|
|
||||||
//feed the arguments in
|
|
||||||
Toy_pushLiteralArray(&arguments, n);
|
|
||||||
|
|
||||||
if (args) {
|
|
||||||
for (int i = 0; i < args->count; i++) {
|
|
||||||
Toy_pushLiteralArray(&arguments, args->literals[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_callLiteralFn(interpreter, fn, &arguments, &returns);
|
|
||||||
|
|
||||||
ret = Toy_popLiteralArray(&returns);
|
|
||||||
|
|
||||||
Toy_freeLiteralArray(&arguments);
|
|
||||||
Toy_freeLiteralArray(&returns);
|
|
||||||
|
|
||||||
Toy_freeLiteral(n);
|
|
||||||
Toy_freeLiteral(fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal Box_callNode(Box_Node* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args) {
|
|
||||||
//call "fnName" on this node, and all children, if it exists
|
|
||||||
Toy_Literal key = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(fnName));
|
|
||||||
|
|
||||||
Toy_Literal ret = Box_callNodeLiteral(node, interpreter, key, args);
|
|
||||||
|
|
||||||
Toy_freeLiteral(key);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box_callRecursiveNodeLiteral(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args) {
|
|
||||||
//if this fn exists
|
|
||||||
if (Toy_existsLiteralDictionary(node->functions, key)) {
|
|
||||||
Toy_Literal fn = Toy_getLiteralDictionary(node->functions, key);
|
|
||||||
Toy_Literal n = TOY_TO_OPAQUE_LITERAL(node, node->tag);
|
|
||||||
|
|
||||||
Toy_LiteralArray arguments;
|
|
||||||
Toy_LiteralArray returns;
|
|
||||||
Toy_initLiteralArray(&arguments);
|
|
||||||
Toy_initLiteralArray(&returns);
|
|
||||||
|
|
||||||
//feed the arguments in
|
|
||||||
Toy_pushLiteralArray(&arguments, n);
|
|
||||||
|
|
||||||
if (args) {
|
|
||||||
for (int i = 0; i < args->count; i++) {
|
|
||||||
Toy_pushLiteralArray(&arguments, args->literals[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_callLiteralFn(interpreter, fn, &arguments, &returns);
|
|
||||||
|
|
||||||
Toy_freeLiteralArray(&arguments);
|
|
||||||
Toy_freeLiteralArray(&returns);
|
|
||||||
|
|
||||||
Toy_freeLiteral(n);
|
|
||||||
Toy_freeLiteral(fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
//recurse to the (non-tombstone) children
|
|
||||||
for (int i = 0; i < node->count; i++) {
|
|
||||||
if (node->children[i] != NULL) {
|
|
||||||
Box_callRecursiveNodeLiteral(node->children[i], interpreter, key, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box_callRecursiveNode(Box_Node* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args) {
|
|
||||||
//call "fnName" on this node, and all children, if it exists
|
|
||||||
Toy_Literal key = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(fnName));
|
|
||||||
|
|
||||||
Box_callRecursiveNodeLiteral(node, interpreter, key, args);
|
|
||||||
|
|
||||||
Toy_freeLiteral(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Box_getChildCountNode(Box_Node* node) {
|
|
||||||
return node->childCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Box_loadTextureNode(Box_Node* node, const char* fname) {
|
|
||||||
SDL_Surface* surface = IMG_Load(fname);
|
|
||||||
|
|
||||||
if (surface == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
node->texture = SDL_CreateTextureFromSurface(engine.renderer, surface);
|
|
||||||
|
|
||||||
if (node->texture == NULL) {
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_FreeSurface(surface);
|
|
||||||
|
|
||||||
int w, h;
|
|
||||||
SDL_QueryTexture(node->texture, NULL, NULL, &w, &h);
|
|
||||||
SDL_Rect r = { 0, 0, w, h };
|
|
||||||
Box_setRectNode(node, r);
|
|
||||||
Box_setFramesNode(node, 1); //default
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box_freeTextureNode(Box_Node* node) {
|
|
||||||
if (node->texture != NULL) {
|
|
||||||
SDL_DestroyTexture(node->texture);
|
|
||||||
node->texture = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box_setRectNode(Box_Node* node, SDL_Rect rect) {
|
|
||||||
node->rect = rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Rect Box_getRectNode(Box_Node* node) {
|
|
||||||
return node->rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box_setFramesNode(Box_Node* node, int frames) {
|
|
||||||
node->frames = frames;
|
|
||||||
node->currentFrame = 0; //just in case
|
|
||||||
}
|
|
||||||
|
|
||||||
int Box_getFramesNode(Box_Node* node) {
|
|
||||||
return node->frames;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box_setCurrentFrameNode(Box_Node* node, int currentFrame) {
|
|
||||||
node->currentFrame = currentFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Box_getCurrentFrameNode(Box_Node* node) {
|
|
||||||
return node->currentFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box_incrementCurrentFrame(Box_Node* node) {
|
|
||||||
node->currentFrame++;
|
|
||||||
if (node->currentFrame >= node->frames) {
|
|
||||||
node->currentFrame = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Box_setTextNode(Box_Node* node, TTF_Font* font, const char* text, SDL_Color color) {
|
|
||||||
SDL_Surface* surface = TTF_RenderText_Solid(font, text, color);
|
|
||||||
|
|
||||||
node->texture = SDL_CreateTextureFromSurface(engine.renderer, surface);
|
|
||||||
|
|
||||||
node->rect = (SDL_Rect){ .x = 0, .y = 0, .w = surface->w, .h = surface->h };
|
|
||||||
node->frames = 1;
|
|
||||||
node->currentFrame = 0;
|
|
||||||
|
|
||||||
SDL_FreeSurface(surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Box_drawNode(Box_Node* node, SDL_Rect dest) {
|
|
||||||
if (!node->texture) return;
|
|
||||||
SDL_Rect src = node->rect;
|
|
||||||
src.x += src.w * node->currentFrame;
|
|
||||||
SDL_RenderCopy(engine.renderer, node->texture, &src, &dest);
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "box_common.h"
|
|
||||||
|
|
||||||
#include "toy_literal_dictionary.h"
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
|
|
||||||
#define OPAQUE_TAG_NODE 1001
|
|
||||||
|
|
||||||
//forward declare
|
|
||||||
typedef struct Box_private_node Box_Node;
|
|
||||||
|
|
||||||
//the node object, which forms a tree
|
|
||||||
typedef struct Box_private_node {
|
|
||||||
//toy functions, stored in a dict for flexibility
|
|
||||||
Toy_LiteralDictionary* functions;
|
|
||||||
|
|
||||||
//point to the parent
|
|
||||||
Box_Node* parent;
|
|
||||||
|
|
||||||
//BUGFIX: hold the node's scope so it can be popped
|
|
||||||
Toy_Scope* scope;
|
|
||||||
|
|
||||||
//my opaque type tag
|
|
||||||
int tag;
|
|
||||||
|
|
||||||
//use Toy's memory model
|
|
||||||
Box_Node** children;
|
|
||||||
int capacity;
|
|
||||||
int count; //includes tombstones
|
|
||||||
int childCount;
|
|
||||||
|
|
||||||
//rendering-specific features
|
|
||||||
SDL_Texture* texture;
|
|
||||||
SDL_Rect rect; //rendered rect
|
|
||||||
int frames; //horizontal-strip based animations
|
|
||||||
int currentFrame;
|
|
||||||
} Box_Node;
|
|
||||||
|
|
||||||
BOX_API void Box_initNode(Box_Node* node, Toy_Interpreter* interpreter, const unsigned char* tb, size_t size); //run bytecode, then grab all top-level function literals
|
|
||||||
BOX_API void Box_pushNode(Box_Node* node, Box_Node* child); //push to the array (prune tombstones when expanding/copying)
|
|
||||||
BOX_API void Box_freeNode(Box_Node* node); //free this node and all children
|
|
||||||
|
|
||||||
BOX_API Box_Node* Box_getChildNode(Box_Node* node, int index);
|
|
||||||
BOX_API void Box_freeChildNode(Box_Node* node, int index);
|
|
||||||
|
|
||||||
BOX_API void Box_sortChildrenNode(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal fnCompare);
|
|
||||||
|
|
||||||
BOX_API Toy_Literal Box_callNodeLiteral(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args);
|
|
||||||
BOX_API Toy_Literal Box_callNode(Box_Node* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args); //call "fnName" on this node, and only this node, if it exists
|
|
||||||
|
|
||||||
//for calling various lifecycle functions
|
|
||||||
BOX_API void Box_callRecursiveNodeLiteral(Box_Node* node, Toy_Interpreter* interpreter, Toy_Literal key, Toy_LiteralArray* args);
|
|
||||||
BOX_API void Box_callRecursiveNode(Box_Node* node, Toy_Interpreter* interpreter, const char* fnName, Toy_LiteralArray* args); //call "fnName" on this node, and all children, if it exists
|
|
||||||
|
|
||||||
BOX_API int Box_getChildCountNode(Box_Node* node);
|
|
||||||
|
|
||||||
BOX_API int Box_loadTextureNode(Box_Node* node, const char* fname);
|
|
||||||
BOX_API void Box_freeTextureNode(Box_Node* node);
|
|
||||||
|
|
||||||
BOX_API void Box_setRectNode(Box_Node* node, SDL_Rect rect);
|
|
||||||
BOX_API SDL_Rect Box_getRectNode(Box_Node* node);
|
|
||||||
|
|
||||||
BOX_API void Box_setFramesNode(Box_Node* node, int frames);
|
|
||||||
BOX_API int Box_getFramesNode(Box_Node* node);
|
|
||||||
BOX_API void Box_setCurrentFrameNode(Box_Node* node, int currentFrame);
|
|
||||||
BOX_API int Box_getCurrentFrameNode(Box_Node* node);
|
|
||||||
BOX_API void Box_incrementCurrentFrame(Box_Node* node);
|
|
||||||
|
|
||||||
BOX_API void Box_setTextNode(Box_Node* node, TTF_Font* font, const char* text, SDL_Color color);
|
|
||||||
|
|
||||||
BOX_API void Box_drawNode(Box_Node* node, SDL_Rect dest);
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
#include "dbg_profiler.h"
|
|
||||||
|
|
||||||
#include "toy_memory.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
//https://stackoverflow.com/questions/2347770/how-do-you-clear-the-console-screen-in-c
|
|
||||||
void Dbg_clearConsole()
|
|
||||||
{
|
|
||||||
HANDLE hStdOut;
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
|
||||||
DWORD count;
|
|
||||||
DWORD cellCount;
|
|
||||||
COORD homeCoords = { 0, 0 };
|
|
||||||
|
|
||||||
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
if (hStdOut == INVALID_HANDLE_VALUE) return;
|
|
||||||
|
|
||||||
/* Get the number of cells in the current buffer */
|
|
||||||
if (!GetConsoleScreenBufferInfo(hStdOut, &csbi)) return;
|
|
||||||
cellCount = csbi.dwSize.X * csbi.dwSize.Y;
|
|
||||||
|
|
||||||
/* Fill the entire buffer with spaces */
|
|
||||||
if (!FillConsoleOutputCharacter(
|
|
||||||
hStdOut,
|
|
||||||
(TCHAR)' ',
|
|
||||||
cellCount,
|
|
||||||
homeCoords,
|
|
||||||
&count
|
|
||||||
)) return;
|
|
||||||
|
|
||||||
/* Fill the entire buffer with the current colors and attributes */
|
|
||||||
if (!FillConsoleOutputAttribute(
|
|
||||||
hStdOut,
|
|
||||||
csbi.wAttributes,
|
|
||||||
cellCount,
|
|
||||||
homeCoords,
|
|
||||||
&count
|
|
||||||
)) return;
|
|
||||||
|
|
||||||
/* Move the cursor home */
|
|
||||||
SetConsoleCursorPosition(hStdOut, homeCoords);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // !_WIN32
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <term.h>
|
|
||||||
|
|
||||||
void Dbg_clearConsole()
|
|
||||||
{
|
|
||||||
if (!cur_term)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
setupterm(NULL, STDOUT_FILENO, &result);
|
|
||||||
if (result <= 0) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
putp(tigetstr("clear"));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Dbg_initTimer(Dbg_Timer* timer) {
|
|
||||||
timer->name = NULL;
|
|
||||||
timer->start = 0;
|
|
||||||
memset(timer->log, 0, 2048);
|
|
||||||
timer->logPos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dbg_startTimer(Dbg_Timer* timer, const char* name) {
|
|
||||||
timer->name = name;
|
|
||||||
timer->start = clock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dbg_stopTimer(Dbg_Timer* timer) {
|
|
||||||
double duration = (clock() - timer->start) / (double) CLOCKS_PER_SEC * 1000;
|
|
||||||
timer->logPos += sprintf(&(timer->log[timer->logPos]), "%.3fms %s\n", duration, timer->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dbg_printTimerLog(Dbg_Timer* timer) {
|
|
||||||
printf("%.*s", timer->logPos, timer->log);
|
|
||||||
timer->logPos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dbg_freeTimer(Dbg_Timer* timer) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dbg_initFPSCounter(Dbg_FPSCounter* counter) {
|
|
||||||
counter->count = 0;
|
|
||||||
counter->start = clock();
|
|
||||||
memset(counter->log, 0, 256);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dbg_tickFPSCounter(Dbg_FPSCounter* counter) {
|
|
||||||
counter->count++;
|
|
||||||
|
|
||||||
if (clock() - counter->start > CLOCKS_PER_SEC) {
|
|
||||||
sprintf(counter->log, "%d FPS", counter->count);
|
|
||||||
counter->start = clock();
|
|
||||||
counter->count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dbg_printFPSCounter(Dbg_FPSCounter* counter) {
|
|
||||||
printf("%s\n", counter->log);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dbg_freeFPSCounter(Dbg_FPSCounter* counter) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
void Dbg_clearConsole();
|
|
||||||
|
|
||||||
typedef struct Dbg_Timer {
|
|
||||||
const char* name;
|
|
||||||
clock_t start;
|
|
||||||
char log[2048];
|
|
||||||
int logPos;
|
|
||||||
} Dbg_Timer;
|
|
||||||
|
|
||||||
void Dbg_initTimer(Dbg_Timer*);
|
|
||||||
void Dbg_startTimer(Dbg_Timer*, const char* name);
|
|
||||||
void Dbg_stopTimer(Dbg_Timer*);
|
|
||||||
void Dbg_printTimerLog(Dbg_Timer*);
|
|
||||||
void Dbg_freeTimer(Dbg_Timer*);
|
|
||||||
|
|
||||||
typedef struct Dbg_FPSCounter {
|
|
||||||
int count;
|
|
||||||
clock_t start;
|
|
||||||
char log[256];
|
|
||||||
} Dbg_FPSCounter;
|
|
||||||
|
|
||||||
void Dbg_initFPSCounter(Dbg_FPSCounter*);
|
|
||||||
void Dbg_tickFPSCounter(Dbg_FPSCounter*);
|
|
||||||
void Dbg_printFPSCounter(Dbg_FPSCounter*);
|
|
||||||
void Dbg_freeFPSCounter(Dbg_FPSCounter*);
|
|
||||||
162
box/lib_about.c
162
box/lib_about.c
@@ -1,162 +0,0 @@
|
|||||||
#include "lib_about.h"
|
|
||||||
|
|
||||||
#include "toy_memory.h"
|
|
||||||
|
|
||||||
int Toy_hookAbout(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
|
||||||
//the about keys
|
|
||||||
Toy_Literal majorKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("major"));
|
|
||||||
Toy_Literal minorKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("minor"));
|
|
||||||
Toy_Literal patchKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("patch"));
|
|
||||||
Toy_Literal buildKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("build"));
|
|
||||||
Toy_Literal authorKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("author"));
|
|
||||||
|
|
||||||
//the about identifiers
|
|
||||||
Toy_Literal majorIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("major"));
|
|
||||||
Toy_Literal minorIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("minor"));
|
|
||||||
Toy_Literal patchIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("patch"));
|
|
||||||
Toy_Literal buildIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("build"));
|
|
||||||
Toy_Literal authorIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("author"));
|
|
||||||
|
|
||||||
//the about values
|
|
||||||
Toy_Literal majorLiteral = TOY_TO_INTEGER_LITERAL(TOY_VERSION_MAJOR);
|
|
||||||
Toy_Literal minorLiteral = TOY_TO_INTEGER_LITERAL(TOY_VERSION_MINOR);
|
|
||||||
Toy_Literal patchLiteral = TOY_TO_INTEGER_LITERAL(TOY_VERSION_PATCH);
|
|
||||||
Toy_Literal buildLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(TOY_VERSION_BUILD));
|
|
||||||
Toy_Literal authorLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("Kayne Ruse, KR Game Studios"));
|
|
||||||
|
|
||||||
//store as 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);
|
|
||||||
|
|
||||||
Toy_freeLiteral(majorKeyLiteral);
|
|
||||||
Toy_freeLiteral(minorKeyLiteral);
|
|
||||||
Toy_freeLiteral(patchKeyLiteral);
|
|
||||||
Toy_freeLiteral(buildKeyLiteral);
|
|
||||||
Toy_freeLiteral(authorKeyLiteral);
|
|
||||||
|
|
||||||
Toy_freeLiteral(majorIdentifierLiteral);
|
|
||||||
Toy_freeLiteral(minorIdentifierLiteral);
|
|
||||||
Toy_freeLiteral(patchIdentifierLiteral);
|
|
||||||
Toy_freeLiteral(buildIdentifierLiteral);
|
|
||||||
Toy_freeLiteral(authorIdentifierLiteral);
|
|
||||||
|
|
||||||
Toy_freeLiteral(majorLiteral);
|
|
||||||
Toy_freeLiteral(minorLiteral);
|
|
||||||
Toy_freeLiteral(patchLiteral);
|
|
||||||
Toy_freeLiteral(buildLiteral);
|
|
||||||
Toy_freeLiteral(authorLiteral);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//create the dictionary to load up with values
|
|
||||||
Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
|
||||||
Toy_initLiteralDictionary(dictionary);
|
|
||||||
|
|
||||||
//set each key/value pair
|
|
||||||
Toy_setLiteralDictionary(dictionary, majorKeyLiteral, majorLiteral);
|
|
||||||
Toy_setLiteralDictionary(dictionary, minorKeyLiteral, minorLiteral);
|
|
||||||
Toy_setLiteralDictionary(dictionary, patchKeyLiteral, patchLiteral);
|
|
||||||
Toy_setLiteralDictionary(dictionary, buildKeyLiteral, buildLiteral);
|
|
||||||
Toy_setLiteralDictionary(dictionary, authorKeyLiteral, authorLiteral);
|
|
||||||
|
|
||||||
//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 anyType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_ANY, true);
|
|
||||||
TOY_TYPE_PUSH_SUBTYPE(&type, strType);
|
|
||||||
TOY_TYPE_PUSH_SUBTYPE(&type, anyType);
|
|
||||||
|
|
||||||
//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);
|
|
||||||
}
|
|
||||||
|
|
||||||
//store globally
|
|
||||||
else {
|
|
||||||
//make sure the names aren't taken
|
|
||||||
if (Toy_isDelcaredScopeVariable(interpreter->scope, majorKeyLiteral) ||
|
|
||||||
Toy_isDelcaredScopeVariable(interpreter->scope, minorKeyLiteral) ||
|
|
||||||
Toy_isDelcaredScopeVariable(interpreter->scope, patchKeyLiteral) ||
|
|
||||||
Toy_isDelcaredScopeVariable(interpreter->scope, buildKeyLiteral) ||
|
|
||||||
Toy_isDelcaredScopeVariable(interpreter->scope, authorKeyLiteral)) {
|
|
||||||
interpreter->errorOutput("Can't override an existing variable\n");
|
|
||||||
Toy_freeLiteral(alias);
|
|
||||||
|
|
||||||
Toy_freeLiteral(majorKeyLiteral);
|
|
||||||
Toy_freeLiteral(minorKeyLiteral);
|
|
||||||
Toy_freeLiteral(patchKeyLiteral);
|
|
||||||
Toy_freeLiteral(buildKeyLiteral);
|
|
||||||
Toy_freeLiteral(authorKeyLiteral);
|
|
||||||
|
|
||||||
Toy_freeLiteral(majorIdentifierLiteral);
|
|
||||||
Toy_freeLiteral(minorIdentifierLiteral);
|
|
||||||
Toy_freeLiteral(patchIdentifierLiteral);
|
|
||||||
Toy_freeLiteral(buildIdentifierLiteral);
|
|
||||||
Toy_freeLiteral(authorIdentifierLiteral);
|
|
||||||
|
|
||||||
Toy_freeLiteral(majorLiteral);
|
|
||||||
Toy_freeLiteral(minorLiteral);
|
|
||||||
Toy_freeLiteral(patchLiteral);
|
|
||||||
Toy_freeLiteral(buildLiteral);
|
|
||||||
Toy_freeLiteral(authorLiteral);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal intType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_INTEGER, true);
|
|
||||||
Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true);
|
|
||||||
|
|
||||||
//major
|
|
||||||
Toy_declareScopeVariable(interpreter->scope, majorIdentifierLiteral, intType);
|
|
||||||
Toy_setScopeVariable(interpreter->scope, majorIdentifierLiteral, majorLiteral, false);
|
|
||||||
|
|
||||||
//minor
|
|
||||||
Toy_declareScopeVariable(interpreter->scope, minorIdentifierLiteral, intType);
|
|
||||||
Toy_setScopeVariable(interpreter->scope, minorIdentifierLiteral, minorLiteral, false);
|
|
||||||
|
|
||||||
//patch
|
|
||||||
Toy_declareScopeVariable(interpreter->scope, patchIdentifierLiteral, intType);
|
|
||||||
Toy_setScopeVariable(interpreter->scope, patchIdentifierLiteral, patchLiteral, false);
|
|
||||||
|
|
||||||
//build
|
|
||||||
Toy_declareScopeVariable(interpreter->scope, buildIdentifierLiteral, strType);
|
|
||||||
Toy_setScopeVariable(interpreter->scope, buildIdentifierLiteral, buildLiteral, false);
|
|
||||||
|
|
||||||
//author
|
|
||||||
Toy_declareScopeVariable(interpreter->scope, authorIdentifierLiteral, strType);
|
|
||||||
Toy_setScopeVariable(interpreter->scope, authorIdentifierLiteral, authorLiteral, false);
|
|
||||||
|
|
||||||
Toy_freeLiteral(intType);
|
|
||||||
Toy_freeLiteral(strType);
|
|
||||||
}
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(majorKeyLiteral);
|
|
||||||
Toy_freeLiteral(minorKeyLiteral);
|
|
||||||
Toy_freeLiteral(patchKeyLiteral);
|
|
||||||
Toy_freeLiteral(buildKeyLiteral);
|
|
||||||
Toy_freeLiteral(authorKeyLiteral);
|
|
||||||
|
|
||||||
Toy_freeLiteral(majorIdentifierLiteral);
|
|
||||||
Toy_freeLiteral(minorIdentifierLiteral);
|
|
||||||
Toy_freeLiteral(patchIdentifierLiteral);
|
|
||||||
Toy_freeLiteral(buildIdentifierLiteral);
|
|
||||||
Toy_freeLiteral(authorIdentifierLiteral);
|
|
||||||
|
|
||||||
Toy_freeLiteral(majorLiteral);
|
|
||||||
Toy_freeLiteral(minorLiteral);
|
|
||||||
Toy_freeLiteral(patchLiteral);
|
|
||||||
Toy_freeLiteral(buildLiteral);
|
|
||||||
Toy_freeLiteral(authorLiteral);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
|
|
||||||
int Toy_hookAbout(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
|
||||||
|
|
||||||
221
box/lib_engine.c
221
box/lib_engine.c
@@ -1,221 +0,0 @@
|
|||||||
#include "lib_engine.h"
|
|
||||||
|
|
||||||
#include "box_engine.h"
|
|
||||||
|
|
||||||
#include "repl_tools.h"
|
|
||||||
#include "toy_memory.h"
|
|
||||||
#include "toy_drive_system.h"
|
|
||||||
#include "toy_literal_array.h"
|
|
||||||
|
|
||||||
#include "toy_console_colors.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
//errors here should be fatal
|
|
||||||
static void fatalError(char* message) {
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "%s" TOY_CC_RESET, message);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//native functions to be called
|
|
||||||
static int nativeInitWindow(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
if (engine.window != NULL) {
|
|
||||||
fatalError("Can't re-initialize the window\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arguments->count != 4) {
|
|
||||||
fatalError("Incorrect number of arguments passed to initWindow\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//extract the arguments
|
|
||||||
Toy_Literal fscreen = Toy_popLiteralArray(arguments);
|
|
||||||
Toy_Literal screenHeight = Toy_popLiteralArray(arguments);
|
|
||||||
Toy_Literal screenWidth = Toy_popLiteralArray(arguments);
|
|
||||||
Toy_Literal caption = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal captionIdn = caption;
|
|
||||||
if (TOY_IS_IDENTIFIER(caption) && Toy_parseIdentifierToValue(interpreter, &caption)) {
|
|
||||||
Toy_freeLiteral(captionIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal screenWidthIdn = screenWidth;
|
|
||||||
if (TOY_IS_IDENTIFIER(screenWidth) && Toy_parseIdentifierToValue(interpreter, &screenWidth)) {
|
|
||||||
Toy_freeLiteral(screenWidthIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal screenHeightIdn = screenHeight;
|
|
||||||
if (TOY_IS_IDENTIFIER(screenHeight) && Toy_parseIdentifierToValue(interpreter, &screenHeight)) {
|
|
||||||
Toy_freeLiteral(screenHeightIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal fscreenIdn = fscreen;
|
|
||||||
if (TOY_IS_IDENTIFIER(fscreen) && Toy_parseIdentifierToValue(interpreter, &fscreen)) {
|
|
||||||
Toy_freeLiteral(fscreenIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
//check argument types
|
|
||||||
if (!TOY_IS_STRING(caption) || !TOY_IS_INTEGER(screenWidth) || !TOY_IS_INTEGER(screenHeight) || !TOY_IS_BOOLEAN(fscreen)) {
|
|
||||||
fatalError("Incorrect argument type passed to initWindow\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//init the window
|
|
||||||
engine.window = SDL_CreateWindow(
|
|
||||||
Toy_toCString(TOY_AS_STRING(caption)),
|
|
||||||
SDL_WINDOWPOS_UNDEFINED,
|
|
||||||
SDL_WINDOWPOS_UNDEFINED,
|
|
||||||
engine.screenWidth = TOY_AS_INTEGER(screenWidth),
|
|
||||||
engine.screenHeight = TOY_AS_INTEGER(screenHeight),
|
|
||||||
TOY_IS_TRUTHY(fscreen) ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE
|
|
||||||
);
|
|
||||||
|
|
||||||
if (engine.window == NULL) {
|
|
||||||
fatalError("Failed to initialize the window\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
//init the renderer
|
|
||||||
// SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
|
|
||||||
engine.renderer = SDL_CreateRenderer(engine.window, -1, SDL_RENDERER_ACCELERATED);
|
|
||||||
|
|
||||||
if (engine.renderer == NULL) {
|
|
||||||
fatalError("Failed to initialize the renderer\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_RendererInfo rendererInfo;
|
|
||||||
SDL_GetRendererInfo(engine.renderer, &rendererInfo);
|
|
||||||
|
|
||||||
printf("Renderer: %s (HW %s)\n", rendererInfo.name, rendererInfo.flags & SDL_RENDERER_ACCELERATED ? "yes" : "no");
|
|
||||||
|
|
||||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
|
|
||||||
SDL_RenderSetLogicalSize(engine.renderer, engine.screenWidth, engine.screenHeight);
|
|
||||||
|
|
||||||
//only run with a window
|
|
||||||
engine.running = true;
|
|
||||||
|
|
||||||
Toy_freeLiteral(caption);
|
|
||||||
Toy_freeLiteral(screenWidth);
|
|
||||||
Toy_freeLiteral(screenHeight);
|
|
||||||
Toy_freeLiteral(fscreen);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeLoadRootNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments passed to loadRootNode\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//extract the arguments
|
|
||||||
Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal drivePathLiteralIdn = drivePathLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
|
|
||||||
Toy_freeLiteral(drivePathLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
//check argument types
|
|
||||||
if (!TOY_IS_STRING(drivePathLiteral)) {
|
|
||||||
interpreter->errorOutput("Incorrect argument type passed to loadRootNode\n");
|
|
||||||
Toy_freeLiteral(drivePathLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &drivePathLiteral);
|
|
||||||
|
|
||||||
Toy_freeLiteral(drivePathLiteral); //not needed anymore
|
|
||||||
|
|
||||||
if (!TOY_IS_STRING(filePathLiteral)) {
|
|
||||||
Toy_freeLiteral(filePathLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//set the signal that a new node is needed
|
|
||||||
engine.nextRootNodeFilename = Toy_copyLiteral(filePathLiteral);
|
|
||||||
|
|
||||||
Toy_freeLiteral(filePathLiteral);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeGetRootNode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
if (arguments->count != 0) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments passed to getRootNode\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (engine.rootNode == NULL) {
|
|
||||||
interpreter->errorOutput("Can't access root node until after initialization\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal resultLiteral = TOY_TO_OPAQUE_LITERAL(engine.rootNode, engine.rootNode->tag);
|
|
||||||
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//call the hook
|
|
||||||
typedef struct Natives {
|
|
||||||
char* name;
|
|
||||||
Toy_NativeFn fn;
|
|
||||||
} Natives;
|
|
||||||
|
|
||||||
int Box_hookEngine(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
|
||||||
//build the natives list
|
|
||||||
Natives natives[] = {
|
|
||||||
{"initWindow", nativeInitWindow},
|
|
||||||
{"loadRootNode", nativeLoadRootNode},
|
|
||||||
{"getRootNode", nativeGetRootNode},
|
|
||||||
{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 false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//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 Box_hookEngine(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
|
||||||
|
|
||||||
130
box/lib_input.c
130
box/lib_input.c
@@ -1,130 +0,0 @@
|
|||||||
#include "lib_input.h"
|
|
||||||
|
|
||||||
#include "box_common.h"
|
|
||||||
#include "box_engine.h"
|
|
||||||
|
|
||||||
#include "toy_memory.h"
|
|
||||||
|
|
||||||
static int nativeMapInputEventToKey(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments, Toy_LiteralDictionary* symKeyEventsPtr, char* fnName) {
|
|
||||||
//checks
|
|
||||||
if (arguments->count != 2) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments passed to ");
|
|
||||||
interpreter->errorOutput(fnName);
|
|
||||||
interpreter->errorOutput("\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal symLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
Toy_Literal evtLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal evtLiteralIdn = evtLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(evtLiteral) && Toy_parseIdentifierToValue(interpreter, &evtLiteral)) {
|
|
||||||
Toy_freeLiteral(evtLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal symLiteralIdn = symLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(symLiteral) && Toy_parseIdentifierToValue(interpreter, &symLiteral)) {
|
|
||||||
Toy_freeLiteral(symLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TOY_IS_STRING(symLiteral) || !TOY_IS_STRING(evtLiteral)) {
|
|
||||||
interpreter->errorOutput("Incorrect type of arguments passed to mapInputEventToKey\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//use the keycode for faster lookups
|
|
||||||
SDL_Keycode keycode = SDL_GetKeyFromName( Toy_toCString(TOY_AS_STRING(symLiteral)) );
|
|
||||||
|
|
||||||
if (keycode == SDLK_UNKNOWN) {
|
|
||||||
interpreter->errorOutput("Unknown key found: ");
|
|
||||||
interpreter->errorOutput(SDL_GetError());
|
|
||||||
interpreter->errorOutput("\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal keycodeLiteral = TOY_TO_INTEGER_LITERAL( (int)keycode );
|
|
||||||
|
|
||||||
//save the sym-event pair
|
|
||||||
Toy_setLiteralDictionary(symKeyEventsPtr, keycodeLiteral, evtLiteral); //I could possibly map multiple events to one sym
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(symLiteral);
|
|
||||||
Toy_freeLiteral(evtLiteral);
|
|
||||||
Toy_freeLiteral(keycodeLiteral);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//dry wrappers
|
|
||||||
static int nativeMapInputEventToKeyDown(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
return nativeMapInputEventToKey(interpreter, arguments, &engine.symKeyDownEvents, "mapInputEventToKeyDown");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeMapInputEventToKeyUp(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
return nativeMapInputEventToKey(interpreter, arguments, &engine.symKeyUpEvents, "mapInputEventToKeyUp");
|
|
||||||
}
|
|
||||||
|
|
||||||
//call the hook
|
|
||||||
typedef struct Natives {
|
|
||||||
char* name;
|
|
||||||
Toy_NativeFn fn;
|
|
||||||
} Natives;
|
|
||||||
|
|
||||||
int Box_hookInput(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
|
||||||
//build the natives list
|
|
||||||
Natives natives[] = {
|
|
||||||
{"mapInputEventToKeyDown", nativeMapInputEventToKeyDown},
|
|
||||||
{"mapInputEventToKeyUp", nativeMapInputEventToKeyUp},
|
|
||||||
// {"mapInputEventToMouse", nativeMapInputEventToMouse},
|
|
||||||
{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 false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//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 Box_hookInput(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
|
||||||
|
|
||||||
1209
box/lib_node.c
1209
box/lib_node.c
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
|
|
||||||
int Box_hookNode(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
|
||||||
|
|
||||||
196
box/lib_random.c
196
box/lib_random.c
@@ -1,196 +0,0 @@
|
|||||||
#include "lib_random.h"
|
|
||||||
|
|
||||||
#include "toy_memory.h"
|
|
||||||
|
|
||||||
static int hashInt(int x) {
|
|
||||||
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
|
||||||
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
|
||||||
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
|
||||||
x = (x >> 16) ^ x;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct Toy_RandomGenerator {
|
|
||||||
int seed; //mutated with each call
|
|
||||||
} Toy_RandomGenerator;
|
|
||||||
|
|
||||||
//Toy native functions
|
|
||||||
static int nativeCreateRandomGenerator(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to createRandomGenerator\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the seed argument
|
|
||||||
Toy_Literal seedLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal seedLiteralIdn = seedLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(seedLiteral) && Toy_parseIdentifierToValue(interpreter, &seedLiteral)) {
|
|
||||||
Toy_freeLiteral(seedLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_IS_IDENTIFIER(seedLiteral)) {
|
|
||||||
Toy_freeLiteral(seedLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!TOY_IS_INTEGER(seedLiteral)) {
|
|
||||||
interpreter->errorOutput("Incorrect literal type passed to createRandomGenerator");
|
|
||||||
Toy_freeLiteral(seedLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//generate the generator object
|
|
||||||
Toy_RandomGenerator* generator = TOY_ALLOCATE(Toy_RandomGenerator, 1);
|
|
||||||
generator->seed = TOY_AS_INTEGER(seedLiteral);
|
|
||||||
Toy_Literal generatorLiteral = TOY_TO_OPAQUE_LITERAL(generator, TOY_OPAQUE_TAG_RANDOM);
|
|
||||||
|
|
||||||
//return and cleanup
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, generatorLiteral);
|
|
||||||
|
|
||||||
Toy_freeLiteral(seedLiteral);
|
|
||||||
Toy_freeLiteral(generatorLiteral);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeGenerateRandomNumber(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to generateRandomNumber\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the runner object
|
|
||||||
Toy_Literal generatorLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal generatorLiteralIdn = generatorLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(generatorLiteral) && Toy_parseIdentifierToValue(interpreter, &generatorLiteral)) {
|
|
||||||
Toy_freeLiteral(generatorLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_IS_IDENTIFIER(generatorLiteral)) {
|
|
||||||
Toy_freeLiteral(generatorLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_GET_OPAQUE_TAG(generatorLiteral) != TOY_OPAQUE_TAG_RANDOM) {
|
|
||||||
interpreter->errorOutput("Unrecognized opaque literal in generateRandomNumber\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_RandomGenerator* generator = TOY_AS_OPAQUE(generatorLiteral);
|
|
||||||
|
|
||||||
//generate the new value and package up the return
|
|
||||||
generator->seed = hashInt(generator->seed);
|
|
||||||
|
|
||||||
Toy_Literal resultLiteral = TOY_TO_INTEGER_LITERAL(generator->seed);
|
|
||||||
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(generatorLiteral);
|
|
||||||
Toy_freeLiteral(resultLiteral);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeFreeRandomGenerator(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to freeRandomGenerator\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the runner object
|
|
||||||
Toy_Literal generatorLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal generatorLiteralIdn = generatorLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(generatorLiteral) && Toy_parseIdentifierToValue(interpreter, &generatorLiteral)) {
|
|
||||||
Toy_freeLiteral(generatorLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_IS_IDENTIFIER(generatorLiteral)) {
|
|
||||||
Toy_freeLiteral(generatorLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_GET_OPAQUE_TAG(generatorLiteral) != TOY_OPAQUE_TAG_RANDOM) {
|
|
||||||
interpreter->errorOutput("Unrecognized opaque literal in freeRandomGenerator\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_RandomGenerator* generator = TOY_AS_OPAQUE(generatorLiteral);
|
|
||||||
|
|
||||||
//clear out the runner object
|
|
||||||
TOY_FREE(Toy_RandomGenerator, generator);
|
|
||||||
Toy_freeLiteral(generatorLiteral);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//call the hook
|
|
||||||
typedef struct Natives {
|
|
||||||
const char* name;
|
|
||||||
Toy_NativeFn fn;
|
|
||||||
} Natives;
|
|
||||||
|
|
||||||
int Toy_hookRandom(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
|
||||||
//build the natives list
|
|
||||||
Natives natives[] = {
|
|
||||||
{"createRandomGenerator", nativeCreateRandomGenerator},
|
|
||||||
{"generateRandomNumber", nativeGenerateRandomNumber},
|
|
||||||
{"freeRandomGenerator", nativeFreeRandomGenerator},
|
|
||||||
{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,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
|
|
||||||
int Toy_hookRandom(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
|
||||||
|
|
||||||
#define TOY_OPAQUE_TAG_RANDOM 200
|
|
||||||
553
box/lib_runner.c
553
box/lib_runner.c
@@ -1,553 +0,0 @@
|
|||||||
#include "lib_runner.h"
|
|
||||||
|
|
||||||
#include "toy_memory.h"
|
|
||||||
#include "toy_drive_system.h"
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
|
|
||||||
#include "repl_tools.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
typedef struct Toy_Runner {
|
|
||||||
Toy_Interpreter interpreter;
|
|
||||||
const unsigned char* bytecode;
|
|
||||||
size_t size;
|
|
||||||
|
|
||||||
bool dirty;
|
|
||||||
} Toy_Runner;
|
|
||||||
|
|
||||||
//Toy native functions
|
|
||||||
static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to loadScript\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the file path literal with a handle
|
|
||||||
Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal drivePathLiteralIdn = drivePathLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
|
|
||||||
Toy_freeLiteral(drivePathLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_IS_IDENTIFIER(drivePathLiteral)) {
|
|
||||||
Toy_freeLiteral(drivePathLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &drivePathLiteral);
|
|
||||||
|
|
||||||
if (TOY_IS_NULL(filePathLiteral)) {
|
|
||||||
Toy_freeLiteral(filePathLiteral);
|
|
||||||
Toy_freeLiteral(drivePathLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_freeLiteral(drivePathLiteral);
|
|
||||||
|
|
||||||
//use raw types - easier
|
|
||||||
const char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral));
|
|
||||||
size_t filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral));
|
|
||||||
|
|
||||||
//load and compile the bytecode
|
|
||||||
size_t fileSize = 0;
|
|
||||||
const char* source = (const char*)Toy_readFile(filePath, &fileSize);
|
|
||||||
|
|
||||||
if (!source) {
|
|
||||||
interpreter->errorOutput("Failed to load source file\n");
|
|
||||||
Toy_freeLiteral(filePathLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned char* bytecode = Toy_compileString(source, &fileSize);
|
|
||||||
free((void*)source);
|
|
||||||
|
|
||||||
if (!bytecode) {
|
|
||||||
interpreter->errorOutput("Failed to compile source file\n");
|
|
||||||
Toy_freeLiteral(filePathLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//build the runner object
|
|
||||||
Toy_Runner* runner = TOY_ALLOCATE(Toy_Runner, 1);
|
|
||||||
Toy_setInterpreterPrint(&runner->interpreter, interpreter->printOutput);
|
|
||||||
Toy_setInterpreterAssert(&runner->interpreter, interpreter->assertOutput);
|
|
||||||
Toy_setInterpreterError(&runner->interpreter, interpreter->errorOutput);
|
|
||||||
runner->interpreter.hooks = interpreter->hooks;
|
|
||||||
runner->interpreter.scope = NULL;
|
|
||||||
Toy_resetInterpreter(&runner->interpreter);
|
|
||||||
runner->bytecode = bytecode;
|
|
||||||
runner->size = fileSize;
|
|
||||||
runner->dirty = false;
|
|
||||||
|
|
||||||
//build the opaque object, and push it to the stack
|
|
||||||
Toy_Literal runnerLiteral = TOY_TO_OPAQUE_LITERAL(runner, TOY_OPAQUE_TAG_RUNNER);
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, runnerLiteral);
|
|
||||||
|
|
||||||
//free the drive path
|
|
||||||
Toy_freeLiteral(filePathLiteral);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to loadScriptBytecode\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the argument
|
|
||||||
Toy_Literal drivePathLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal drivePathLiteralIdn = drivePathLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(drivePathLiteral) && Toy_parseIdentifierToValue(interpreter, &drivePathLiteral)) {
|
|
||||||
Toy_freeLiteral(drivePathLiteralIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_IS_IDENTIFIER(drivePathLiteral)) {
|
|
||||||
Toy_freeLiteral(drivePathLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &drivePathLiteral);
|
|
||||||
|
|
||||||
if (TOY_IS_NULL(filePathLiteral)) {
|
|
||||||
Toy_freeLiteral(filePathLiteral);
|
|
||||||
Toy_freeLiteral(drivePathLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_freeLiteral(drivePathLiteral);
|
|
||||||
|
|
||||||
//use raw types - easier
|
|
||||||
const char* filePath = Toy_toCString(TOY_AS_STRING(filePathLiteral));
|
|
||||||
size_t filePathLength = Toy_lengthRefString(TOY_AS_STRING(filePathLiteral));
|
|
||||||
|
|
||||||
//load the bytecode
|
|
||||||
size_t fileSize = 0;
|
|
||||||
unsigned char* bytecode = (unsigned char*)Toy_readFile(filePath, &fileSize);
|
|
||||||
|
|
||||||
if (!bytecode) {
|
|
||||||
interpreter->errorOutput("Failed to load bytecode file\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//build the runner object
|
|
||||||
Toy_Runner* runner = TOY_ALLOCATE(Toy_Runner, 1);
|
|
||||||
Toy_setInterpreterPrint(&runner->interpreter, interpreter->printOutput);
|
|
||||||
Toy_setInterpreterAssert(&runner->interpreter, interpreter->assertOutput);
|
|
||||||
Toy_setInterpreterError(&runner->interpreter, interpreter->errorOutput);
|
|
||||||
runner->interpreter.hooks = interpreter->hooks;
|
|
||||||
runner->interpreter.scope = NULL;
|
|
||||||
Toy_resetInterpreter(&runner->interpreter);
|
|
||||||
runner->bytecode = bytecode;
|
|
||||||
runner->size = fileSize;
|
|
||||||
runner->dirty = false;
|
|
||||||
|
|
||||||
//build the opaque object, and push it to the stack
|
|
||||||
Toy_Literal runnerLiteral = TOY_TO_OPAQUE_LITERAL(runner, TOY_OPAQUE_TAG_RUNNER);
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, runnerLiteral);
|
|
||||||
|
|
||||||
//free the drive path
|
|
||||||
Toy_freeLiteral(filePathLiteral);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeRunScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to runScript\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the runner object
|
|
||||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal runnerIdn = runnerLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
|
||||||
Toy_freeLiteral(runnerIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_IS_IDENTIFIER(runnerLiteral)) {
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
|
||||||
interpreter->errorOutput("Unrecognized opaque literal in runScript\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
|
||||||
|
|
||||||
//run
|
|
||||||
if (runner->dirty) {
|
|
||||||
interpreter->errorOutput("Can't re-run a dirty script (try resetting it first)\n");
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char* bytecodeCopy = TOY_ALLOCATE(unsigned char, runner->size);
|
|
||||||
memcpy(bytecodeCopy, runner->bytecode, runner->size); //need a COPY of the bytecode, because the interpreter eats it
|
|
||||||
|
|
||||||
Toy_runInterpreter(&runner->interpreter, bytecodeCopy, runner->size);
|
|
||||||
runner->dirty = true;
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeGetScriptVar(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 2) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to getScriptVar\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the runner object
|
|
||||||
Toy_Literal varName = Toy_popLiteralArray(arguments);
|
|
||||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal varNameIdn = varName;
|
|
||||||
if (TOY_IS_IDENTIFIER(varName) && Toy_parseIdentifierToValue(interpreter, &varName)) {
|
|
||||||
Toy_freeLiteral(varNameIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal runnerIdn = runnerLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
|
||||||
Toy_freeLiteral(runnerIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_IS_IDENTIFIER(varName) || TOY_IS_IDENTIFIER(runnerLiteral)) {
|
|
||||||
Toy_freeLiteral(varName);
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
|
||||||
interpreter->errorOutput("Unrecognized opaque literal in getScriptVar\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
|
||||||
|
|
||||||
//dirty check
|
|
||||||
if (!runner->dirty) {
|
|
||||||
interpreter->errorOutput("Can't access variable from a non-dirty script (try running it first)\n");
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the desired variable
|
|
||||||
Toy_Literal varIdn = TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_STRING(varName)));
|
|
||||||
Toy_Literal result = TOY_TO_NULL_LITERAL;
|
|
||||||
Toy_getScopeVariable(runner->interpreter.scope, varIdn, &result);
|
|
||||||
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(result);
|
|
||||||
Toy_freeLiteral(varIdn);
|
|
||||||
Toy_freeLiteral(varName);
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeCallScriptFn(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count < 2) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to callScriptFn\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the rest args
|
|
||||||
Toy_LiteralArray tmp;
|
|
||||||
Toy_initLiteralArray(&tmp);
|
|
||||||
|
|
||||||
while (arguments->count > 2) {
|
|
||||||
Toy_Literal lit = Toy_popLiteralArray(arguments);
|
|
||||||
Toy_pushLiteralArray(&tmp, lit);
|
|
||||||
Toy_freeLiteral(lit);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_LiteralArray rest;
|
|
||||||
Toy_initLiteralArray(&rest);
|
|
||||||
|
|
||||||
while (tmp.count > 0) { //correct the order of the rest args
|
|
||||||
Toy_Literal lit = Toy_popLiteralArray(&tmp);
|
|
||||||
Toy_pushLiteralArray(&rest, lit);
|
|
||||||
Toy_freeLiteral(lit);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_freeLiteralArray(&tmp);
|
|
||||||
|
|
||||||
//get the runner object
|
|
||||||
Toy_Literal varName = Toy_popLiteralArray(arguments);
|
|
||||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal varNameIdn = varName;
|
|
||||||
if (TOY_IS_IDENTIFIER(varName) && Toy_parseIdentifierToValue(interpreter, &varName)) {
|
|
||||||
Toy_freeLiteral(varNameIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal runnerIdn = runnerLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
|
||||||
Toy_freeLiteral(runnerIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_IS_IDENTIFIER(varName) || TOY_IS_IDENTIFIER(runnerLiteral)) {
|
|
||||||
Toy_freeLiteral(varName);
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
|
||||||
interpreter->errorOutput("Unrecognized opaque literal in callScriptFn\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
|
||||||
|
|
||||||
//dirty check
|
|
||||||
if (!runner->dirty) {
|
|
||||||
interpreter->errorOutput("Can't access fn from a non-dirty script (try running it first)\n");
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
Toy_freeLiteralArray(&rest);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the desired variable
|
|
||||||
Toy_Literal varIdn = TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_STRING(varName)));
|
|
||||||
Toy_Literal fn = TOY_TO_NULL_LITERAL;
|
|
||||||
Toy_getScopeVariable(runner->interpreter.scope, varIdn, &fn);
|
|
||||||
|
|
||||||
if (!TOY_IS_FUNCTION(fn)) {
|
|
||||||
interpreter->errorOutput("Can't run a non-function literal\n");
|
|
||||||
Toy_freeLiteral(fn);
|
|
||||||
Toy_freeLiteral(varIdn);
|
|
||||||
Toy_freeLiteral(varName);
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
Toy_freeLiteralArray(&rest);
|
|
||||||
}
|
|
||||||
|
|
||||||
//call
|
|
||||||
Toy_LiteralArray resultArray;
|
|
||||||
Toy_initLiteralArray(&resultArray);
|
|
||||||
|
|
||||||
Toy_callLiteralFn(interpreter, fn, &rest, &resultArray);
|
|
||||||
|
|
||||||
Toy_Literal result = TOY_TO_NULL_LITERAL;
|
|
||||||
if (resultArray.count > 0) {
|
|
||||||
result = Toy_popLiteralArray(&resultArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteralArray(&resultArray);
|
|
||||||
Toy_freeLiteral(result);
|
|
||||||
Toy_freeLiteral(fn);
|
|
||||||
Toy_freeLiteral(varIdn);
|
|
||||||
Toy_freeLiteral(varName);
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
Toy_freeLiteralArray(&rest);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeResetScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to resetScript\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the runner object
|
|
||||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal runnerIdn = runnerLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
|
||||||
Toy_freeLiteral(runnerIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_IS_IDENTIFIER(runnerLiteral)) {
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
|
||||||
interpreter->errorOutput("Unrecognized opaque literal in resetScript\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
|
||||||
|
|
||||||
//reset
|
|
||||||
if (!runner->dirty) {
|
|
||||||
interpreter->errorOutput("Can't reset a non-dirty script (try running it first)\n");
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_resetInterpreter(&runner->interpreter);
|
|
||||||
runner->dirty = false;
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeFreeScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to freeScript\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the runner object
|
|
||||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal runnerIdn = runnerLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
|
||||||
Toy_freeLiteral(runnerIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_IS_IDENTIFIER(runnerLiteral)) {
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
|
||||||
interpreter->errorOutput("Unrecognized opaque literal in freeScript\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
|
||||||
|
|
||||||
//clear out the runner object
|
|
||||||
runner->interpreter.hooks = NULL;
|
|
||||||
Toy_freeInterpreter(&runner->interpreter);
|
|
||||||
TOY_FREE_ARRAY(unsigned char, runner->bytecode, runner->size);
|
|
||||||
|
|
||||||
TOY_FREE(Toy_Runner, runner);
|
|
||||||
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nativeCheckScriptDirty(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
|
||||||
//no arguments
|
|
||||||
if (arguments->count != 1) {
|
|
||||||
interpreter->errorOutput("Incorrect number of arguments to checkScriptDirty\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the runner object
|
|
||||||
Toy_Literal runnerLiteral = Toy_popLiteralArray(arguments);
|
|
||||||
|
|
||||||
Toy_Literal runnerIdn = runnerLiteral;
|
|
||||||
if (TOY_IS_IDENTIFIER(runnerLiteral) && Toy_parseIdentifierToValue(interpreter, &runnerLiteral)) {
|
|
||||||
Toy_freeLiteral(runnerIdn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_IS_IDENTIFIER(runnerLiteral)) {
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
|
|
||||||
interpreter->errorOutput("Unrecognized opaque literal in checkScriptDirty\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Runner* runner = TOY_AS_OPAQUE(runnerLiteral);
|
|
||||||
|
|
||||||
//run
|
|
||||||
Toy_Literal result = TOY_TO_BOOLEAN_LITERAL(runner->dirty);
|
|
||||||
|
|
||||||
Toy_pushLiteralArray(&interpreter->stack, result);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteral(result);
|
|
||||||
Toy_freeLiteral(runnerLiteral);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//call the hook
|
|
||||||
typedef struct Natives {
|
|
||||||
const char* name;
|
|
||||||
Toy_NativeFn fn;
|
|
||||||
} Natives;
|
|
||||||
|
|
||||||
int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
|
||||||
//build the natives list
|
|
||||||
Natives natives[] = {
|
|
||||||
{"loadScript", nativeLoadScript},
|
|
||||||
{"loadScriptBytecode", nativeLoadScriptBytecode},
|
|
||||||
{"runScript", nativeRunScript},
|
|
||||||
{"getScriptVar", nativeGetScriptVar},
|
|
||||||
{"callScriptFn", nativeCallScriptFn},
|
|
||||||
{"resetScript", nativeResetScript},
|
|
||||||
{"freeScript", nativeFreeScript},
|
|
||||||
{"checkScriptDirty", nativeCheckScriptDirty},
|
|
||||||
{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,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
|
|
||||||
int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
|
||||||
|
|
||||||
#define TOY_OPAQUE_TAG_RUNNER 100
|
|
||||||
|
|
||||||
2117
box/lib_standard.c
2117
box/lib_standard.c
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
|
|
||||||
int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
|
||||||
|
|
||||||
51
box/makefile
51
box/makefile
@@ -1,51 +0,0 @@
|
|||||||
CC=gcc
|
|
||||||
|
|
||||||
IDIR+=. ../Toy/source
|
|
||||||
CFLAGS+=$(addprefix -I,$(IDIR)) -g -Wall -W -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable
|
|
||||||
LIBS+=-lSDL2 -lSDL2_image -ltoy
|
|
||||||
|
|
||||||
ODIR = obj
|
|
||||||
SRC = $(wildcard *.c)
|
|
||||||
OBJ = $(addprefix $(ODIR)/,$(SRC:.c=.o))
|
|
||||||
|
|
||||||
REPLLIBS = $(wildcard ../Toy/repl/lib*) $(wildcard ../Toy/repl/repl_tools.*)
|
|
||||||
|
|
||||||
OUTNAME=box
|
|
||||||
|
|
||||||
ifeq ($(findstring CYGWIN, $(shell uname)),CYGWIN)
|
|
||||||
LIBLINE =-Wl,--out-implib=$(BOX_OUTDIR)/lib$(OUTNAME).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive $(OBJ) -Wl,--no-whole-archive
|
|
||||||
OUT=$(BOX_OUTDIR)/$(OUTNAME).dll
|
|
||||||
else ifeq ($(shell uname),Linux)
|
|
||||||
LIBLINE=-Wl,--out-implib=./$(BOX_OUTDIR)/lib$(OUTNAME).a -Wl,--whole-archive $(OBJ) -Wl,--no-whole-archive
|
|
||||||
OUT=./$(BOX_OUTDIR)/lib$(OUTNAME).so
|
|
||||||
CFLAGS += -fPIC
|
|
||||||
else ifeq ($(OS),Windows_NT)
|
|
||||||
LIBLINE =-Wl,--out-implib=$(BOX_OUTDIR)/lib$(OUTNAME).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive $(OBJ) -Wl,--no-whole-archive
|
|
||||||
OUT=$(BOX_OUTDIR)/$(OUTNAME).dll
|
|
||||||
else
|
|
||||||
@echo "Platform test failed - what platform is this?"
|
|
||||||
exit 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
library: repllibs $(OBJ)
|
|
||||||
$(CC) -DBOX_EXPORT $(CFLAGS) -shared -o $(OUT) $(LIBLINE) -L../$(LIBDIR) $(LIBS)
|
|
||||||
|
|
||||||
static: repllibs $(OBJ)
|
|
||||||
ar crs $(BOX_OUTDIR)/lib$(OUTNAME).a $(OBJ) -L../$(LIBDIR) $(LIBS)
|
|
||||||
|
|
||||||
#copy the stuff from Toy/repl that is needed
|
|
||||||
repllibs:
|
|
||||||
cp $(REPLLIBS) .
|
|
||||||
|
|
||||||
$(OBJ): | $(ODIR)
|
|
||||||
|
|
||||||
$(ODIR):
|
|
||||||
mkdir $(ODIR)
|
|
||||||
|
|
||||||
$(ODIR)/%.o: %.c
|
|
||||||
$(CC) -c -o $@ $< $(CFLAGS)
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
|
|
||||||
clean-repllibs:
|
|
||||||
$(RM) $(notdir $(REPLLIBS))
|
|
||||||
207
box/repl_tools.c
207
box/repl_tools.c
@@ -1,207 +0,0 @@
|
|||||||
#include "repl_tools.h"
|
|
||||||
#include "lib_about.h"
|
|
||||||
#include "lib_standard.h"
|
|
||||||
#include "lib_random.h"
|
|
||||||
#include "lib_runner.h"
|
|
||||||
|
|
||||||
#include "toy_console_colors.h"
|
|
||||||
|
|
||||||
#include "toy_lexer.h"
|
|
||||||
#include "toy_parser.h"
|
|
||||||
#include "toy_compiler.h"
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
//IO functions
|
|
||||||
const unsigned char* Toy_readFile(const char* path, size_t* fileSize) {
|
|
||||||
FILE* file = fopen(path, "rb");
|
|
||||||
|
|
||||||
if (file == NULL) {
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "Could not open file \"%s\"\n" TOY_CC_RESET, path);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(file, 0L, SEEK_END);
|
|
||||||
*fileSize = ftell(file);
|
|
||||||
rewind(file);
|
|
||||||
|
|
||||||
unsigned char* buffer = (unsigned char*)malloc(*fileSize + 1);
|
|
||||||
|
|
||||||
if (buffer == NULL) {
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "Not enough memory to read \"%s\"\n" TOY_CC_RESET, path);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t bytesRead = fread(buffer, sizeof(unsigned char), *fileSize, file);
|
|
||||||
|
|
||||||
buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this
|
|
||||||
|
|
||||||
if (bytesRead < *fileSize) {
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "Could not read file \"%s\"\n" TOY_CC_RESET, path);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Toy_writeFile(const char* path, const unsigned char* bytes, size_t size) {
|
|
||||||
FILE* file = fopen(path, "wb");
|
|
||||||
|
|
||||||
if (file == NULL) {
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "Could not open file \"%s\"\n" TOY_CC_RESET, path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t written = fwrite(bytes, size, 1, file);
|
|
||||||
|
|
||||||
if (written != 1) {
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "Could not write file \"%s\"\n" TOY_CC_RESET, path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//repl functions
|
|
||||||
const unsigned char* Toy_compileString(const char* source, size_t* size) {
|
|
||||||
Toy_Lexer lexer;
|
|
||||||
Toy_Parser parser;
|
|
||||||
Toy_Compiler compiler;
|
|
||||||
|
|
||||||
Toy_initLexer(&lexer, source);
|
|
||||||
Toy_initParser(&parser, &lexer);
|
|
||||||
Toy_initCompiler(&compiler);
|
|
||||||
|
|
||||||
//step 1 - run the parser until the end of the source
|
|
||||||
Toy_ASTNode* node = Toy_scanParser(&parser);
|
|
||||||
while(node != NULL) {
|
|
||||||
//on error, pack up and leave
|
|
||||||
if (node->type == TOY_AST_NODE_ERROR) {
|
|
||||||
Toy_freeASTNode(node);
|
|
||||||
Toy_freeCompiler(&compiler);
|
|
||||||
Toy_freeParser(&parser);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_writeCompiler(&compiler, node);
|
|
||||||
Toy_freeASTNode(node);
|
|
||||||
node = Toy_scanParser(&parser);
|
|
||||||
}
|
|
||||||
|
|
||||||
//step 2 - get the bytecode dump
|
|
||||||
const unsigned char* tb = Toy_collateCompiler(&compiler, size);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeCompiler(&compiler);
|
|
||||||
Toy_freeParser(&parser);
|
|
||||||
//no lexer to clean up
|
|
||||||
|
|
||||||
//finally
|
|
||||||
return tb;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Toy_runBinary(const unsigned char* tb, size_t size) {
|
|
||||||
Toy_Interpreter interpreter;
|
|
||||||
Toy_initInterpreter(&interpreter);
|
|
||||||
|
|
||||||
//inject the libs
|
|
||||||
Toy_injectNativeHook(&interpreter, "about", Toy_hookAbout);
|
|
||||||
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
|
||||||
Toy_injectNativeHook(&interpreter, "random", Toy_hookRandom);
|
|
||||||
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
|
||||||
|
|
||||||
Toy_runInterpreter(&interpreter, tb, (int)size);
|
|
||||||
Toy_freeInterpreter(&interpreter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Toy_runBinaryFile(const char* fname) {
|
|
||||||
size_t size = 0; //not used
|
|
||||||
const unsigned char* tb = Toy_readFile(fname, &size);
|
|
||||||
if (!tb) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Toy_runBinary(tb, size);
|
|
||||||
//interpreter takes ownership of the binary data
|
|
||||||
}
|
|
||||||
|
|
||||||
void Toy_runSource(const char* source) {
|
|
||||||
size_t size = 0;
|
|
||||||
const unsigned char* tb = Toy_compileString(source, &size);
|
|
||||||
if (!tb) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_runBinary(tb, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Toy_runSourceFile(const char* fname) {
|
|
||||||
size_t size = 0; //not used
|
|
||||||
const char* source = (const char*)Toy_readFile(fname, &size);
|
|
||||||
if (!source) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Toy_runSource(source);
|
|
||||||
free((void*)source);
|
|
||||||
}
|
|
||||||
|
|
||||||
//utils for debugging the header
|
|
||||||
static unsigned char readByte(const unsigned char* tb, int* count) {
|
|
||||||
unsigned char ret = *(unsigned char*)(tb + *count);
|
|
||||||
*count += 1;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* readString(const unsigned char* tb, int* count) {
|
|
||||||
const unsigned char* ret = tb + *count;
|
|
||||||
*count += strlen((char*)ret) + 1; //+1 for null character
|
|
||||||
return (const char*)ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Toy_parseBinaryFileHeader(const char* fname) {
|
|
||||||
size_t size = 0; //not used
|
|
||||||
const unsigned char* tb = Toy_readFile(fname, &size);
|
|
||||||
if (!tb || size < 4) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
//header section
|
|
||||||
const unsigned char major = readByte(tb, &count);
|
|
||||||
const unsigned char minor = readByte(tb, &count);
|
|
||||||
const unsigned char patch = readByte(tb, &count);
|
|
||||||
|
|
||||||
const char* build = readString(tb, &count);
|
|
||||||
|
|
||||||
printf("Toy Programming Language Interpreter Version %d.%d.%d (interpreter built on %s)\n\n", TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH, TOY_VERSION_BUILD);
|
|
||||||
|
|
||||||
printf("Toy Programming Language Bytecode Version ");
|
|
||||||
|
|
||||||
//print the output
|
|
||||||
if (major == TOY_VERSION_MAJOR && minor == TOY_VERSION_MINOR && patch == TOY_VERSION_PATCH) {
|
|
||||||
printf("%d.%d.%d", major, minor, patch);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf(TOY_CC_FONT_YELLOW TOY_CC_BACK_BLACK "%d.%d.%d" TOY_CC_RESET, major, minor, patch);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(" (interpreter built on ");
|
|
||||||
|
|
||||||
if (strncmp(build, TOY_VERSION_BUILD, strlen(TOY_VERSION_BUILD)) == 0) {
|
|
||||||
printf("%s", build);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf(TOY_CC_FONT_YELLOW TOY_CC_BACK_BLACK "%s" TOY_CC_RESET, build);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(")\n");
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
free((void*)tb);
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "toy_common.h"
|
|
||||||
|
|
||||||
const unsigned char* Toy_readFile(const char* path, size_t* fileSize);
|
|
||||||
int Toy_writeFile(const char* path, const unsigned char* bytes, size_t size);
|
|
||||||
|
|
||||||
const unsigned char* Toy_compileString(const char* source, size_t* size);
|
|
||||||
|
|
||||||
void Toy_runBinary(const unsigned char* tb, size_t size);
|
|
||||||
void Toy_runBinaryFile(const char* fname);
|
|
||||||
void Toy_runSource(const char* source);
|
|
||||||
void Toy_runSourceFile(const char* fname);
|
|
||||||
|
|
||||||
void Toy_parseBinaryFileHeader(const char* fname);
|
|
||||||
46
makefile
46
makefile
@@ -1,34 +1,19 @@
|
|||||||
export OUTDIR = out
|
export OUTDIR = out
|
||||||
export LIBDIR = lib
|
export BOX_OUTDIR = ../$(OUTDIR)
|
||||||
export TOY_OUTDIR = ../$(LIBDIR)
|
export TOY_OUTDIR = ../../$(OUTDIR)
|
||||||
export BOX_OUTDIR = ../$(LIBDIR)
|
|
||||||
|
|
||||||
all: $(OUTDIR) $(LIBDIR) toy box
|
all: $(OUTDIR) toy box
|
||||||
$(MAKE) -j8 -C source
|
$(MAKE) -j8 -C source
|
||||||
ifeq ($(findstring CYGWIN, $(shell uname)),CYGWIN)
|
|
||||||
cp $(LIBDIR)/*.dll $(OUTDIR)
|
|
||||||
else ifeq ($(shell uname),Linux)
|
|
||||||
cp $(LIBDIR)/*.so $(OUTDIR)
|
|
||||||
else ifeq ($(OS),Windows_NT)
|
|
||||||
cp $(LIBDIR)/*.dll $(OUTDIR)
|
|
||||||
endif
|
|
||||||
|
|
||||||
test: clean $(OUTDIR) toy box
|
|
||||||
$(MAKE) -C test
|
|
||||||
|
|
||||||
toy: $(LIBDIR)
|
toy: $(LIBDIR)
|
||||||
$(MAKE) -j8 -C Toy/source
|
$(MAKE) -j8 -C Box/Toy/source
|
||||||
|
|
||||||
box: $(LIBDIR)
|
box: $(LIBDIR)
|
||||||
$(MAKE) -j8 -C box repllibs
|
$(MAKE) -j8 -C Box/source
|
||||||
$(MAKE) -j8 -C box library
|
|
||||||
|
|
||||||
$(OUTDIR):
|
$(OUTDIR):
|
||||||
mkdir $(OUTDIR)
|
mkdir $(OUTDIR)
|
||||||
|
|
||||||
$(LIBDIR):
|
|
||||||
mkdir $(LIBDIR)
|
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@@ -56,24 +41,3 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
rebuild: clean all
|
rebuild: clean all
|
||||||
|
|
||||||
|
|
||||||
#utils for the manual android build
|
|
||||||
INCLUDEDIR=include
|
|
||||||
|
|
||||||
SOURCEDIR=bundle
|
|
||||||
|
|
||||||
$(INCLUDEDIR):
|
|
||||||
mkdir $(INCLUDEDIR)
|
|
||||||
|
|
||||||
$(SOURCEDIR):
|
|
||||||
mkdir $(SOURCEDIR)
|
|
||||||
|
|
||||||
sourcelist:
|
|
||||||
@echo $(addprefix ../airport/,$(wildcard Toy/source/*.c) $(wildcard box/*.c) $(wildcard source/*.c)) > source.list
|
|
||||||
|
|
||||||
bundleincludes: $(INCLUDEDIR)
|
|
||||||
cp $(addprefix ../airport/,$(wildcard Toy/source/*.h) $(wildcard box/*.h) $(wildcard source/*.h)) $(INCLUDEDIR)
|
|
||||||
|
|
||||||
bundlesource: $(SOURCEDIR)
|
|
||||||
cp $(addprefix ../airport/,$(wildcard Toy/source/*.c) $(wildcard box/*.c) $(wildcard source/*.c)) $(SOURCEDIR)
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
CC=gcc
|
|
||||||
|
|
||||||
IDIR+=. ../Toy/source ../box
|
|
||||||
CFLAGS+=$(addprefix -I,$(IDIR)) -DSDL_MAIN_HANDLED -g -Wall -W -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable
|
|
||||||
LIBS+=-lSDL2 -lSDL2_image -ltoy -lbox
|
|
||||||
|
|
||||||
ODIR = obj
|
|
||||||
TARGETS = $(wildcard ../box/*.c)
|
|
||||||
TESTS = $(wildcard *.c)
|
|
||||||
OBJ = $(addprefix $(ODIR)/,$(TARGETS:../box/%.c=%.o)) $(addprefix $(ODIR)/,$(TESTS:.c=.o))
|
|
||||||
|
|
||||||
.PRECIOUS: $(TESTS:%.c=../$(OUTDIR)/%.exe)
|
|
||||||
|
|
||||||
all: $(OBJ) $(TESTS:%.c=../$(OUTDIR)/%.exe)
|
|
||||||
|
|
||||||
../$(OUTDIR)/%.exe: $(ODIR)/%.o
|
|
||||||
ifeq ($(shell uname),Linux)
|
|
||||||
@$(CC) -o $@ $< $(TARGETS:../box/%.c=$(ODIR)/%.o) $(CFLAGS) -Wl,-rpath,../out -L../$(LIBDIR) $(LIBS)
|
|
||||||
cp ../$(LIBDIR)/*.so ../$(OUTDIR)
|
|
||||||
valgrind --leak-check=full --track-origins=yes $@
|
|
||||||
else
|
|
||||||
@$(CC) -o $@ $< $(TARGETS:../box/%.c=$(ODIR)/%.o) $(CFLAGS) -L../$(LIBDIR) $(LIBS)
|
|
||||||
cp ../$(LIBDIR)/*.dll ../$(OUTDIR)
|
|
||||||
$@
|
|
||||||
endif
|
|
||||||
|
|
||||||
$(OBJ): | $(ODIR)
|
|
||||||
|
|
||||||
$(ODIR):
|
|
||||||
mkdir $(ODIR)
|
|
||||||
|
|
||||||
$(ODIR)/%.o: %.c
|
|
||||||
@$(CC) -c -o $@ $< $(CFLAGS)
|
|
||||||
|
|
||||||
$(ODIR)/%.o: ../box/%.c
|
|
||||||
@$(CC) -c -o $@ $< $(CFLAGS)
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
|
|
||||||
clean:
|
|
||||||
$(RM) $(ODIR)
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
var tally: int = 0;
|
|
||||||
|
|
||||||
fn onInit(node: opaque) {
|
|
||||||
print "child init called";
|
|
||||||
}
|
|
||||||
|
|
||||||
fn onStep(node: opaque) {
|
|
||||||
print "child step called";
|
|
||||||
print ++tally;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn onFree(node: opaque) {
|
|
||||||
print "child free called";
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
fn onInit(node: opaque) {
|
|
||||||
print "init called";
|
|
||||||
}
|
|
||||||
|
|
||||||
fn onStep(node: opaque) {
|
|
||||||
print "step called";
|
|
||||||
}
|
|
||||||
|
|
||||||
fn onFree(node: opaque) {
|
|
||||||
print "free called";
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
#include "box_engine_node.h"
|
|
||||||
|
|
||||||
#include "toy_lexer.h"
|
|
||||||
#include "toy_parser.h"
|
|
||||||
#include "toy_compiler.h"
|
|
||||||
#include "toy_interpreter.h"
|
|
||||||
#include "toy_console_colors.h"
|
|
||||||
#include "toy_memory.h"
|
|
||||||
|
|
||||||
#include "repl_tools.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
//suppress the print keyword
|
|
||||||
static void noPrintFn(const char* output) {
|
|
||||||
//NO OP
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
{
|
|
||||||
//setup interpreter
|
|
||||||
Toy_Interpreter interpreter;
|
|
||||||
Toy_initInterpreter(&interpreter);
|
|
||||||
Toy_setInterpreterPrint(&interpreter, noPrintFn);
|
|
||||||
|
|
||||||
size_t size = 0;
|
|
||||||
|
|
||||||
const char* source = Toy_readFile("./scripts/parent_engine_node.toy", &size);
|
|
||||||
const unsigned char* tb = Toy_compileString(source, &size);
|
|
||||||
|
|
||||||
//create and test the engine node
|
|
||||||
Box_EngineNode* node = TOY_ALLOCATE(Box_EngineNode, 1);
|
|
||||||
|
|
||||||
Box_initEngineNode(node, &interpreter, tb, size);
|
|
||||||
|
|
||||||
Toy_Literal nodeLiteral = TOY_TO_OPAQUE_LITERAL(node, OPAQUE_TAG_ENGINE_NODE);
|
|
||||||
|
|
||||||
//argument list to pass in the node
|
|
||||||
Toy_LiteralArray arguments;
|
|
||||||
Toy_initLiteralArray(&arguments);
|
|
||||||
|
|
||||||
//call each function
|
|
||||||
Box_callRecursiveEngineNode(node, &interpreter, "onInit", &arguments);
|
|
||||||
Box_callRecursiveEngineNode(node, &interpreter, "onStep", &arguments);
|
|
||||||
Box_callRecursiveEngineNode(node, &interpreter, "onQuit", &arguments);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteralArray(&arguments);
|
|
||||||
Box_freeEngineNode(node);
|
|
||||||
free((void*)source);
|
|
||||||
|
|
||||||
Toy_freeInterpreter(&interpreter);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
//setup interpreter
|
|
||||||
Toy_Interpreter interpreter;
|
|
||||||
Toy_initInterpreter(&interpreter);
|
|
||||||
Toy_setInterpreterPrint(&interpreter, noPrintFn);
|
|
||||||
|
|
||||||
size_t size = 0;
|
|
||||||
|
|
||||||
const char* source = Toy_readFile("./scripts/parent_engine_node.toy", &size);
|
|
||||||
const unsigned char* tb = Toy_compileString(source, &size);
|
|
||||||
|
|
||||||
//create and test the engine node
|
|
||||||
Box_EngineNode* node = TOY_ALLOCATE(Box_EngineNode, 1);
|
|
||||||
|
|
||||||
Box_initEngineNode(node, &interpreter, tb, size);
|
|
||||||
Toy_resetInterpreter(&interpreter);
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
const char* source = Toy_readFile("./scripts/child_engine_node.toy", &size);
|
|
||||||
const unsigned char* tb = Toy_compileString(source, &size);
|
|
||||||
|
|
||||||
Box_EngineNode* child = TOY_ALLOCATE(Box_EngineNode, 1);
|
|
||||||
Box_initEngineNode(child, &interpreter, tb, size);
|
|
||||||
Toy_resetInterpreter(&interpreter);
|
|
||||||
|
|
||||||
Box_pushEngineNode(node, child);
|
|
||||||
|
|
||||||
free((void*)source);
|
|
||||||
}
|
|
||||||
|
|
||||||
//argument list to pass in each time
|
|
||||||
Toy_LiteralArray arguments;
|
|
||||||
Toy_initLiteralArray(&arguments);
|
|
||||||
|
|
||||||
//test the calls
|
|
||||||
Box_callRecursiveEngineNode(node, &interpreter, "onInit", &arguments);
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
Box_callRecursiveEngineNode(node, &interpreter, "onStep", &arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
Box_callRecursiveEngineNode(node, &interpreter, "onFree", &arguments);
|
|
||||||
|
|
||||||
//cleanup
|
|
||||||
Toy_freeLiteralArray(&arguments);
|
|
||||||
Box_freeEngineNode(node); //frees all children
|
|
||||||
free((void*)source);
|
|
||||||
|
|
||||||
Toy_freeInterpreter(&interpreter);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user