Compare commits

...

21 Commits

Author SHA1 Message Date
Kayne Ruse d3df01c1c4 Updated .gitignore 2023-02-23 03:33:52 +11:00
Ratstail91 cdca6fa45c Fixed directory in solution file 2023-02-22 20:06:48 +11:00
Kayne Ruse 1dde9d8f29 Improved error message in set() and push()
The actual issue was that the type check wasn't catching the issue, so
it reached the scope before it was caught. Fixed it, anyway.
2023-02-20 13:04:35 +00:00
Kayne Ruse 7f0f17b6e0 Patched up failures from Toy_parseIdentifierToValue
I really don't like that function - it needs to be replaced.
2023-02-20 06:11:30 +00:00
Kayne Ruse 3507104121 Fixed indexAccess potentially going awry with bad inputs
There's always one or two that slip through
2023-02-20 05:28:25 +00:00
Kayne Ruse 87de634e30 Updated version number to 1.0.0 2023-02-20 02:08:42 +00:00
Kayne Ruse 6fa224fa7b Hooks can't be dict keys, tweaked Toy_readFile 2023-02-18 16:47:38 +00:00
Kayne Ruse 8a68d864e6 Opaque type check added 2023-02-18 15:21:49 +00:00
Kayne Ruse 49f240ea07 Minor tweak 2023-02-18 12:15:23 +00:00
Kayne Ruse 3acbd7447a Merge remote-tracking branch 'refs/remotes/origin/main' 2023-02-18 11:57:22 +00:00
Kayne Ruse 6f126e6daa Minor tweaks and renames, as I'm documenting 2023-02-18 11:56:18 +00:00
Kayne Ruse 2adb9d9158 Tweaked lib runner API 2023-02-16 22:04:47 +00:00
Kayne Ruse 1668dca255 Tweaked some APIs, hid some functions I don't want in the API 2023-02-16 13:06:07 +00:00
Kayne Ruse 501ff6fff4 Chased a ghost for a few hours 2023-02-14 18:55:24 +00:00
Kayne Ruse 3845627fe5 Added release build to MSVC 2023-02-14 18:03:04 +00:00
Kayne Ruse cdae03bd54 String and identifier making fixed for MSVC, just in case 2023-02-14 17:38:10 +00:00
Kayne Ruse 7b501b71b5 commandLine now initializes with default values 2023-02-14 17:00:16 +00:00
Kayne Ruse 913738a4d1 Tweaked the runner test, should be orders of magnitude faster 2023-02-14 16:16:48 +00:00
Kayne Ruse 3312a38c7c Updated memusage tool 2023-02-14 16:05:43 +00:00
Kayne Ruse 71b57fd42c Fixed scripts for distribution 2023-02-14 10:35:08 +00:00
Kayne Ruse 453afbab41 Fixed a stupid bug in MSVC 2023-02-14 10:24:43 +00:00
45 changed files with 714 additions and 216 deletions
+2
View File
@@ -19,6 +19,8 @@ bin/
*.db *.db
*.o *.o
*.a *.a
*.so
*.dll
*.exe *.exe
*.meta *.meta
*.log *.log
+19 -2
View File
@@ -74,6 +74,10 @@
<OutDir>$(SolutionDir)out\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)out\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> <IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)out\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -109,12 +113,26 @@
<AdditionalLibraryDirectories>$(SolutionDir)out\$(Configuration)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(SolutionDir)out\$(Configuration)</AdditionalLibraryDirectories>
</Link> </Link>
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)/source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard_C>stdc17</LanguageStandard_C>
<PreprocessorDefinitions>
</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<LanguageStandard_C>stdc17</LanguageStandard_C>
<PreprocessorDefinitions>
</PreprocessorDefinitions>
<AdditionalIncludeDirectories>C:\Users\kayne\Desktop\Toy\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>C:\Users\kayne\Desktop\Toy\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link>
<AdditionalLibraryDirectories>$(SolutionDir)out\$(Configuration)</AdditionalLibraryDirectories>
<AdditionalDependencies>Toy.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="repl\lib_about.c" /> <ClCompile Include="repl\lib_about.c" />
<ClCompile Include="repl\lib_compound.c" />
<ClCompile Include="repl\lib_runner.c" /> <ClCompile Include="repl\lib_runner.c" />
<ClCompile Include="repl\lib_standard.c" /> <ClCompile Include="repl\lib_standard.c" />
<ClCompile Include="repl\repl_main.c" /> <ClCompile Include="repl\repl_main.c" />
@@ -122,7 +140,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="repl\lib_about.h" /> <ClInclude Include="repl\lib_about.h" />
<ClInclude Include="repl\lib_compound.h" />
<ClInclude Include="repl\lib_runner.h" /> <ClInclude Include="repl\lib_runner.h" />
<ClInclude Include="repl\lib_standard.h" /> <ClInclude Include="repl\lib_standard.h" />
<ClInclude Include="repl\repl_tools.h" /> <ClInclude Include="repl\repl_tools.h" />
+12 -1
View File
@@ -41,7 +41,7 @@
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
</PropertyGroup> </PropertyGroup>
@@ -73,6 +73,10 @@
<OutDir>$(SolutionDir)out\$(Configuration)\</OutDir> <OutDir>$(SolutionDir)out\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir> <IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)out\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TOY_EXPORTS;TOY_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TOY_EXPORTS;TOY_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -105,6 +109,13 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>TOY_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>TOY_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard_C>stdc17</LanguageStandard_C>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<LanguageStandard_C>stdc17</LanguageStandard_C>
<PreprocessorDefinitions>TOY_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
+44 -1
View File
@@ -7,6 +7,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
typedef struct Toy_Runner { typedef struct Toy_Runner {
Toy_Interpreter interpreter; Toy_Interpreter interpreter;
@@ -32,6 +33,11 @@ static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu
Toy_freeLiteral(drivePathLiteralIdn); Toy_freeLiteral(drivePathLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(drivePathLiteral)) {
Toy_freeLiteral(drivePathLiteral);
return -1;
}
Toy_Literal filePathLiteral = Toy_getFilePathLiteral(interpreter, &drivePathLiteral); Toy_Literal filePathLiteral = Toy_getFilePathLiteral(interpreter, &drivePathLiteral);
if (TOY_IS_NULL(filePathLiteral)) { if (TOY_IS_NULL(filePathLiteral)) {
@@ -48,7 +54,7 @@ static int nativeLoadScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu
//load and compile the bytecode //load and compile the bytecode
size_t fileSize = 0; size_t fileSize = 0;
const char* source = Toy_readFile(filePath, &fileSize); const char* source = (const char*)Toy_readFile(filePath, &fileSize);
if (!source) { if (!source) {
interpreter->errorOutput("Failed to load source file\n"); interpreter->errorOutput("Failed to load source file\n");
@@ -102,6 +108,11 @@ static int nativeLoadScriptBytecode(Toy_Interpreter* interpreter, Toy_LiteralArr
Toy_freeLiteral(drivePathLiteralIdn); Toy_freeLiteral(drivePathLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(drivePathLiteral)) {
Toy_freeLiteral(drivePathLiteral);
return -1;
}
Toy_RefString* drivePath = Toy_copyRefString(TOY_AS_STRING(drivePathLiteral)); Toy_RefString* drivePath = Toy_copyRefString(TOY_AS_STRING(drivePathLiteral));
//get the drive and path as a string (can't trust that pesky strtok - custom split) TODO: move this to refstring library //get the drive and path as a string (can't trust that pesky strtok - custom split) TODO: move this to refstring library
@@ -212,6 +223,11 @@ static int nativeRunScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argum
Toy_freeLiteral(runnerIdn); Toy_freeLiteral(runnerIdn);
} }
if (TOY_IS_IDENTIFIER(runnerLiteral)) {
Toy_freeLiteral(runnerLiteral);
return -1;
}
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
interpreter->errorOutput("Unrecognized opaque literal in runScript\n"); interpreter->errorOutput("Unrecognized opaque literal in runScript\n");
return -1; return -1;
@@ -259,6 +275,12 @@ static int nativeGetScriptVar(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
Toy_freeLiteral(runnerIdn); 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) { if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
interpreter->errorOutput("Unrecognized opaque literal in getScriptVar\n"); interpreter->errorOutput("Unrecognized opaque literal in getScriptVar\n");
return -1; return -1;
@@ -331,6 +353,12 @@ static int nativeCallScriptFn(Toy_Interpreter* interpreter, Toy_LiteralArray* ar
Toy_freeLiteral(runnerIdn); 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) { if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
interpreter->errorOutput("Unrecognized opaque literal in callScriptFn\n"); interpreter->errorOutput("Unrecognized opaque literal in callScriptFn\n");
return -1; return -1;
@@ -400,6 +428,11 @@ static int nativeResetScript(Toy_Interpreter* interpreter, Toy_LiteralArray* arg
Toy_freeLiteral(runnerIdn); Toy_freeLiteral(runnerIdn);
} }
if (TOY_IS_IDENTIFIER(runnerLiteral)) {
Toy_freeLiteral(runnerLiteral);
return -1;
}
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
interpreter->errorOutput("Unrecognized opaque literal in resetScript\n"); interpreter->errorOutput("Unrecognized opaque literal in resetScript\n");
return -1; return -1;
@@ -436,6 +469,11 @@ static int nativeFreeScript(Toy_Interpreter* interpreter, Toy_LiteralArray* argu
Toy_freeLiteral(runnerIdn); Toy_freeLiteral(runnerIdn);
} }
if (TOY_IS_IDENTIFIER(runnerLiteral)) {
Toy_freeLiteral(runnerLiteral);
return -1;
}
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
interpreter->errorOutput("Unrecognized opaque literal in freeScript\n"); interpreter->errorOutput("Unrecognized opaque literal in freeScript\n");
return -1; return -1;
@@ -470,6 +508,11 @@ static int nativeCheckScriptDirty(Toy_Interpreter* interpreter, Toy_LiteralArray
Toy_freeLiteral(runnerIdn); Toy_freeLiteral(runnerIdn);
} }
if (TOY_IS_IDENTIFIER(runnerLiteral)) {
Toy_freeLiteral(runnerLiteral);
return -1;
}
if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) { if (TOY_GET_OPAQUE_TAG(runnerLiteral) != TOY_OPAQUE_TAG_RUNNER) {
interpreter->errorOutput("Unrecognized opaque literal in checkScriptDirty\n"); interpreter->errorOutput("Unrecognized opaque literal in checkScriptDirty\n");
return -1; return -1;
+4 -3
View File
@@ -1,13 +1,14 @@
#pragma once #pragma once
#include "toy_common.h"
#include "toy_interpreter.h" #include "toy_interpreter.h"
int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias); int Toy_hookRunner(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
//file system API - these need to be set by the host //file system API - these need to be set by the host
void Toy_initDriveDictionary(); TOY_API void Toy_initDriveDictionary();
void Toy_freeDriveDictionary(); TOY_API void Toy_freeDriveDictionary();
Toy_LiteralDictionary* Toy_getDriveDictionary(); TOY_API Toy_LiteralDictionary* Toy_getDriveDictionary();
#define TOY_OPAQUE_TAG_RUNNER 100 #define TOY_OPAQUE_TAG_RUNNER 100
+115 -4
View File
@@ -2,9 +2,10 @@
#include "toy_memory.h" #include "toy_memory.h"
#include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <time.h> #include <time.h>
#include <ctype.h>
static int nativeClock(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { static int nativeClock(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//no arguments //no arguments
@@ -53,6 +54,12 @@ static int nativeConcat(Toy_Interpreter* interpreter, Toy_LiteralArray* argument
Toy_freeLiteral(otherLiteralIdn); Toy_freeLiteral(otherLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(otherLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(otherLiteral);
return -1;
}
//for each self type //for each self type
if (TOY_IS_ARRAY(selfLiteral)) { if (TOY_IS_ARRAY(selfLiteral)) {
if (!TOY_IS_ARRAY(otherLiteral)) { if (!TOY_IS_ARRAY(otherLiteral)) {
@@ -163,6 +170,12 @@ static int nativeContainsKey(Toy_Interpreter* interpreter, Toy_LiteralArray* arg
Toy_freeLiteral(keyLiteralIdn); Toy_freeLiteral(keyLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(keyLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(keyLiteral);
return -1;
}
//check type //check type
if (!(/* TOY_IS_ARRAY(selfLiteral) || */ TOY_IS_DICTIONARY(selfLiteral) )) { if (!(/* TOY_IS_ARRAY(selfLiteral) || */ TOY_IS_DICTIONARY(selfLiteral) )) {
interpreter->errorOutput("Incorrect argument type passed to containsKey\n"); interpreter->errorOutput("Incorrect argument type passed to containsKey\n");
@@ -208,6 +221,12 @@ static int nativeContainsValue(Toy_Interpreter* interpreter, Toy_LiteralArray* a
Toy_freeLiteral(valueLiteralIdn); Toy_freeLiteral(valueLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(valueLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(valueLiteral);
return -1;
}
//check type //check type
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) )) { if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) )) {
interpreter->errorOutput("Incorrect argument type passed to containsValue\n"); interpreter->errorOutput("Incorrect argument type passed to containsValue\n");
@@ -278,6 +297,12 @@ static int nativeEvery(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments
Toy_freeLiteral(fnLiteralIdn); Toy_freeLiteral(fnLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(fnLiteral);
return -1;
}
//check type //check type
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
interpreter->errorOutput("Incorrect argument type passed to every\n"); interpreter->errorOutput("Incorrect argument type passed to every\n");
@@ -394,6 +419,12 @@ static int nativeFilter(Toy_Interpreter* interpreter, Toy_LiteralArray* argument
Toy_freeLiteral(fnLiteralIdn); Toy_freeLiteral(fnLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(fnLiteral);
return -1;
}
//check type //check type
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
interpreter->errorOutput("Incorrect argument type passed to filter\n"); interpreter->errorOutput("Incorrect argument type passed to filter\n");
@@ -508,6 +539,12 @@ static int nativeForEach(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen
Toy_freeLiteral(fnLiteralIdn); Toy_freeLiteral(fnLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(fnLiteral);
return -1;
}
//check type //check type
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
interpreter->errorOutput("Incorrect argument type passed to forEach\n"); interpreter->errorOutput("Incorrect argument type passed to forEach\n");
@@ -580,6 +617,11 @@ static int nativeGetKeys(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen
Toy_freeLiteral(selfLiteralIdn); Toy_freeLiteral(selfLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral)) {
Toy_freeLiteral(selfLiteral);
return -1;
}
//check type //check type
if (!TOY_IS_DICTIONARY(selfLiteral)) { if (!TOY_IS_DICTIONARY(selfLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to getKeys\n"); interpreter->errorOutput("Incorrect argument type passed to getKeys\n");
@@ -625,6 +667,11 @@ static int nativeGetValues(Toy_Interpreter* interpreter, Toy_LiteralArray* argum
Toy_freeLiteral(selfLiteralIdn); Toy_freeLiteral(selfLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral)) {
Toy_freeLiteral(selfLiteral);
return -1;
}
//check type //check type
if (!TOY_IS_DICTIONARY(selfLiteral)) { if (!TOY_IS_DICTIONARY(selfLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to getValues\n"); interpreter->errorOutput("Incorrect argument type passed to getValues\n");
@@ -677,6 +724,12 @@ static int nativeIndexOf(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen
Toy_freeLiteral(valueLiteralIdn); Toy_freeLiteral(valueLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(valueLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(valueLiteral);
return -1;
}
//check type //check type
if (!TOY_IS_ARRAY(selfLiteral)) { if (!TOY_IS_ARRAY(selfLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to indexOf\n"); interpreter->errorOutput("Incorrect argument type passed to indexOf\n");
@@ -724,6 +777,12 @@ static int nativeMap(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_freeLiteral(fnLiteralIdn); Toy_freeLiteral(fnLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(fnLiteral);
return -1;
}
//check type //check type
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
interpreter->errorOutput("Incorrect argument type passed to map\n"); interpreter->errorOutput("Incorrect argument type passed to map\n");
@@ -833,6 +892,13 @@ static int nativeReduce(Toy_Interpreter* interpreter, Toy_LiteralArray* argument
Toy_freeLiteral(fnLiteralIdn); Toy_freeLiteral(fnLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(defaultLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(defaultLiteral);
Toy_freeLiteral(fnLiteral);
return -1;
}
//check type //check type
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
interpreter->errorOutput("Incorrect argument type passed to reduce\n"); interpreter->errorOutput("Incorrect argument type passed to reduce\n");
@@ -928,6 +994,12 @@ static int nativeSome(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_freeLiteral(fnLiteralIdn); Toy_freeLiteral(fnLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(fnLiteral);
return -1;
}
//check type //check type
if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { if (!( TOY_IS_ARRAY(selfLiteral) || TOY_IS_DICTIONARY(selfLiteral) ) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
interpreter->errorOutput("Incorrect argument type passed to some\n"); interpreter->errorOutput("Incorrect argument type passed to some\n");
@@ -1092,6 +1164,12 @@ static int nativeSort(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_freeLiteral(fnLiteralIdn); Toy_freeLiteral(fnLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(fnLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(fnLiteral);
return -1;
}
//check type //check type
if (!TOY_IS_ARRAY(selfLiteral) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) { if (!TOY_IS_ARRAY(selfLiteral) || !( TOY_IS_FUNCTION(fnLiteral) || TOY_IS_FUNCTION_NATIVE(fnLiteral) )) {
interpreter->errorOutput("Incorrect argument type passed to sort\n"); interpreter->errorOutput("Incorrect argument type passed to sort\n");
@@ -1128,6 +1206,11 @@ static int nativeToLower(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen
Toy_freeLiteral(selfLiteralIdn); Toy_freeLiteral(selfLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral)) {
Toy_freeLiteral(selfLiteral);
return -1;
}
if (!TOY_IS_STRING(selfLiteral)) { if (!TOY_IS_STRING(selfLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to toLower\n"); interpreter->errorOutput("Incorrect argument type passed to toLower\n");
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
@@ -1189,6 +1272,11 @@ static int nativeToString(Toy_Interpreter* interpreter, Toy_LiteralArray* argume
Toy_freeLiteral(selfLiteralIdn); Toy_freeLiteral(selfLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral)) {
Toy_freeLiteral(selfLiteral);
return -1;
}
//BUGFIX: probably an undefined variable //BUGFIX: probably an undefined variable
if (TOY_IS_IDENTIFIER(selfLiteral)) { if (TOY_IS_IDENTIFIER(selfLiteral)) {
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
@@ -1228,6 +1316,11 @@ static int nativeToUpper(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen
Toy_freeLiteral(selfLiteralIdn); Toy_freeLiteral(selfLiteralIdn);
} }
if (TOY_IS_IDENTIFIER(selfLiteral)) {
Toy_freeLiteral(selfLiteral);
return -1;
}
if (!TOY_IS_STRING(selfLiteral)) { if (!TOY_IS_STRING(selfLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to toUpper\n"); interpreter->errorOutput("Incorrect argument type passed to toUpper\n");
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
@@ -1288,7 +1381,13 @@ static int nativeTrim(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_freeLiteral(selfLiteralIdn); Toy_freeLiteral(selfLiteralIdn);
} }
if (!TOY_IS_STRING(selfLiteral)) { if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(trimCharsLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(trimCharsLiteral);
return -1;
}
if (!TOY_IS_STRING(selfLiteral) || !TOY_IS_STRING(trimCharsLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to trim\n"); interpreter->errorOutput("Incorrect argument type passed to trim\n");
Toy_freeLiteral(trimCharsLiteral); Toy_freeLiteral(trimCharsLiteral);
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
@@ -1399,7 +1498,13 @@ static int nativeTrimBegin(Toy_Interpreter* interpreter, Toy_LiteralArray* argum
Toy_freeLiteral(selfLiteralIdn); Toy_freeLiteral(selfLiteralIdn);
} }
if (!TOY_IS_STRING(selfLiteral)) { if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(trimCharsLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(trimCharsLiteral);
return -1;
}
if (!TOY_IS_STRING(selfLiteral) || !TOY_IS_STRING(trimCharsLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to trimBegin\n"); interpreter->errorOutput("Incorrect argument type passed to trimBegin\n");
Toy_freeLiteral(trimCharsLiteral); Toy_freeLiteral(trimCharsLiteral);
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
@@ -1487,7 +1592,13 @@ static int nativeTrimEnd(Toy_Interpreter* interpreter, Toy_LiteralArray* argumen
Toy_freeLiteral(selfLiteralIdn); Toy_freeLiteral(selfLiteralIdn);
} }
if (!TOY_IS_STRING(selfLiteral)) { if (TOY_IS_IDENTIFIER(selfLiteral) || TOY_IS_IDENTIFIER(trimCharsLiteral)) {
Toy_freeLiteral(selfLiteral);
Toy_freeLiteral(trimCharsLiteral);
return -1;
}
if (!TOY_IS_STRING(selfLiteral) || !TOY_IS_STRING(trimCharsLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to trimEnd\n"); interpreter->errorOutput("Incorrect argument type passed to trimEnd\n");
Toy_freeLiteral(trimCharsLiteral); Toy_freeLiteral(trimCharsLiteral);
Toy_freeLiteral(selfLiteral); Toy_freeLiteral(selfLiteral);
+3 -3
View File
@@ -75,7 +75,7 @@ void repl(const char* initialInput) {
if (!error) { if (!error) {
//get the bytecode dump //get the bytecode dump
int size = 0; size_t size = 0;
unsigned char* tb = Toy_collateCompiler(&compiler, &size); unsigned char* tb = Toy_collateCompiler(&compiler, &size);
//run the bytecode //run the bytecode
@@ -180,7 +180,7 @@ int main(int argc, const char* argv[]) {
//compile and save //compile and save
size_t size = 0; size_t size = 0;
const char* source = Toy_readFile(Toy_commandLine.compilefile, &size); const char* source = (const char*)Toy_readFile(Toy_commandLine.compilefile, &size);
if (!source) { if (!source) {
return 1; return 1;
} }
@@ -220,7 +220,7 @@ int main(int argc, const char* argv[]) {
} }
size_t size; size_t size;
initialSource = Toy_readFile(Toy_commandLine.initialfile, &size); initialSource = (const char*)Toy_readFile(Toy_commandLine.initialfile, &size);
} }
repl(initialSource); repl(initialSource);
+6 -6
View File
@@ -14,7 +14,7 @@
#include <stdlib.h> #include <stdlib.h>
//IO functions //IO functions
const char* Toy_readFile(const char* path, size_t* fileSize) { const unsigned char* Toy_readFile(const char* path, size_t* fileSize) {
FILE* file = fopen(path, "rb"); FILE* file = fopen(path, "rb");
if (file == NULL) { if (file == NULL) {
@@ -26,14 +26,14 @@ const char* Toy_readFile(const char* path, size_t* fileSize) {
*fileSize = ftell(file); *fileSize = ftell(file);
rewind(file); rewind(file);
char* buffer = (char*)malloc(*fileSize + 1); unsigned char* buffer = (unsigned char*)malloc(*fileSize + 1);
if (buffer == NULL) { if (buffer == NULL) {
fprintf(stderr, TOY_CC_ERROR "Not enough memory to read \"%s\"\n" TOY_CC_RESET, path); fprintf(stderr, TOY_CC_ERROR "Not enough memory to read \"%s\"\n" TOY_CC_RESET, path);
return NULL; return NULL;
} }
size_t bytesRead = fread(buffer, sizeof(char), *fileSize, file); size_t bytesRead = fread(buffer, sizeof(unsigned char), *fileSize, file);
buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this
@@ -94,7 +94,7 @@ const unsigned char* Toy_compileString(const char* source, size_t* size) {
} }
//get the bytecode dump //get the bytecode dump
const unsigned char* tb = Toy_collateCompiler(&compiler, (int*)(size)); const unsigned char* tb = Toy_collateCompiler(&compiler, size);
//cleanup //cleanup
Toy_freeCompiler(&compiler); Toy_freeCompiler(&compiler);
@@ -120,7 +120,7 @@ void Toy_runBinary(const unsigned char* tb, size_t size) {
void Toy_runBinaryFile(const char* fname) { void Toy_runBinaryFile(const char* fname) {
size_t size = 0; //not used size_t size = 0; //not used
const unsigned char* tb = (const unsigned char*)Toy_readFile(fname, &size); const unsigned char* tb = Toy_readFile(fname, &size);
if (!tb) { if (!tb) {
return; return;
} }
@@ -140,7 +140,7 @@ void Toy_runSource(const char* source) {
void Toy_runSourceFile(const char* fname) { void Toy_runSourceFile(const char* fname) {
size_t size = 0; //not used size_t size = 0; //not used
const char* source = Toy_readFile(fname, &size); const char* source = (const char*)Toy_readFile(fname, &size);
if (!source) { if (!source) {
return; return;
} }
+1 -1
View File
@@ -2,7 +2,7 @@
#include "toy_common.h" #include "toy_common.h"
const char* Toy_readFile(const char* path, size_t* fileSize); const unsigned char* Toy_readFile(const char* path, size_t* fileSize);
int Toy_writeFile(const char* path, const unsigned char* bytes, size_t size); int Toy_writeFile(const char* path, const unsigned char* bytes, size_t size);
const unsigned char* Toy_compileString(const char* source, size_t* size); const unsigned char* Toy_compileString(const char* source, size_t* size);
+1 -1
View File
@@ -17,5 +17,5 @@ fn fib(n : int) {
for (var i = 0; i < 40; i++) { for (var i = 0; i < 40; i++) {
var res = fib(i); var res = fib(i);
print string i + ": " + string res + "\n"; print string i + ": " + string res;
} }
+2 -1
View File
@@ -1,3 +1,4 @@
//WARNING: please think twice before using this in a test
fn fib(n : int) { fn fib(n : int) {
if (n < 2) return n; if (n < 2) return n;
return fib(n-1) + fib(n-2); return fib(n-1) + fib(n-2);
@@ -5,5 +6,5 @@ fn fib(n : int) {
for (var i = 0; i < 20; i++) { for (var i = 0; i < 20; i++) {
var res = fib(i); var res = fib(i);
print string i + ": " + string res + "\n"; print string i + ": " + string res;
} }
+2 -2
View File
@@ -29,7 +29,7 @@ for (var i = 0; i < SIZE -1; i++) {
prev += " "; prev += " ";
} }
prev += "*"; //initial prev += "*"; //initial
print prev + "\n"; print prev;
//run //run
for (var iteration = 0; iteration < SIZE -1; iteration++) { for (var iteration = 0; iteration < SIZE -1; iteration++) {
@@ -44,6 +44,6 @@ for (var iteration = 0; iteration < SIZE -1; iteration++) {
//right //right
output += (lookup[prev[SIZE-2]][prev[SIZE-1]][" "]); output += (lookup[prev[SIZE-2]][prev[SIZE-1]][" "]);
print output + "\n"; print output;
prev = output; prev = output;
} }
+156 -37
View File
@@ -4,6 +4,7 @@
#include "toy_literal.h" #include "toy_literal.h"
#include <stdio.h> #include <stdio.h>
#include <string.h>
//static math utils, copied from the interpreter //static math utils, copied from the interpreter
static Toy_Literal addition(Toy_Interpreter* interpreter, Toy_Literal lhs, Toy_Literal rhs) { static Toy_Literal addition(Toy_Interpreter* interpreter, Toy_Literal lhs, Toy_Literal rhs) {
@@ -278,6 +279,17 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(first) || TOY_IS_IDENTIFIER(second) || TOY_IS_IDENTIFIER(third)) {
Toy_freeLiteral(op);
Toy_freeLiteral(assign);
Toy_freeLiteral(third);
Toy_freeLiteral(second);
Toy_freeLiteral(first);
Toy_freeLiteral(compound);
return -1;
}
//second and third are bad args to dictionaries //second and third are bad args to dictionaries
if (!TOY_IS_NULL(second) || !TOY_IS_NULL(third)) { if (!TOY_IS_NULL(second) || !TOY_IS_NULL(third)) {
interpreter->errorOutput("Index slicing not allowed for dictionaries\n"); interpreter->errorOutput("Index slicing not allowed for dictionaries\n");
@@ -400,6 +412,17 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(first) || TOY_IS_IDENTIFIER(second) || TOY_IS_IDENTIFIER(third)) {
Toy_freeLiteral(op);
Toy_freeLiteral(assign);
Toy_freeLiteral(third);
Toy_freeLiteral(second);
Toy_freeLiteral(first);
Toy_freeLiteral(compound);
return -1;
}
//handle each error case //handle each error case
if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= TOY_AS_ARRAY(compound)->count) { if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= TOY_AS_ARRAY(compound)->count) {
interpreter->errorOutput("Bad first indexing\n"); interpreter->errorOutput("Bad first indexing\n");
@@ -542,6 +565,17 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(first) || TOY_IS_IDENTIFIER(second) || TOY_IS_IDENTIFIER(third)) {
Toy_freeLiteral(op);
Toy_freeLiteral(assign);
Toy_freeLiteral(third);
Toy_freeLiteral(second);
Toy_freeLiteral(first);
Toy_freeLiteral(compound);
return -1;
}
//handle each error case //handle each error case
if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= TOY_AS_ARRAY(compound)->count) { if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= TOY_AS_ARRAY(compound)->count) {
interpreter->errorOutput("Bad first indexing assignment\n"); interpreter->errorOutput("Bad first indexing assignment\n");
@@ -704,6 +738,17 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(first)) {
Toy_freeLiteral(op);
Toy_freeLiteral(assign);
Toy_freeLiteral(third);
Toy_freeLiteral(second);
Toy_freeLiteral(first);
Toy_freeLiteral(compound);
return -1;
}
Toy_Literal value = Toy_getLiteralArray(TOY_AS_ARRAY(compound), first); Toy_Literal value = Toy_getLiteralArray(TOY_AS_ARRAY(compound), first);
if (TOY_IS_STRING(op) && Toy_equalsRefStringCString(TOY_AS_STRING(op), "+=")) { if (TOY_IS_STRING(op) && Toy_equalsRefStringCString(TOY_AS_STRING(op), "+=")) {
@@ -792,6 +837,17 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(first) || TOY_IS_IDENTIFIER(second) || TOY_IS_IDENTIFIER(third)) {
Toy_freeLiteral(op);
Toy_freeLiteral(assign);
Toy_freeLiteral(third);
Toy_freeLiteral(second);
Toy_freeLiteral(first);
Toy_freeLiteral(compound);
return -1;
}
//handle each error case //handle each error case
if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= (int)Toy_lengthRefString(TOY_AS_STRING(compound))) { if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= (int)Toy_lengthRefString(TOY_AS_STRING(compound))) {
interpreter->errorOutput("Bad first indexing in string\n"); interpreter->errorOutput("Bad first indexing in string\n");
@@ -936,6 +992,17 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(first) || TOY_IS_IDENTIFIER(second) || TOY_IS_IDENTIFIER(third)) {
Toy_freeLiteral(op);
Toy_freeLiteral(assign);
Toy_freeLiteral(third);
Toy_freeLiteral(second);
Toy_freeLiteral(first);
Toy_freeLiteral(compound);
return -1;
}
//handle each error case //handle each error case
if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= (int)Toy_lengthRefString(TOY_AS_STRING(compound))) { if (!TOY_IS_INTEGER(first) || TOY_AS_INTEGER(first) < 0 || TOY_AS_INTEGER(first) >= (int)Toy_lengthRefString(TOY_AS_STRING(compound))) {
interpreter->errorOutput("Bad first indexing in string assignment\n"); interpreter->errorOutput("Bad first indexing in string assignment\n");
@@ -1063,7 +1130,7 @@ int Toy_private_index(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
int Toy_private_set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { int Toy_private_set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//if wrong number of arguments, fail //if wrong number of arguments, fail
if (arguments->count != 3) { if (arguments->count != 3) {
interpreter->errorOutput("Incorrect number of arguments to _set\n"); interpreter->errorOutput("Incorrect number of arguments to set\n");
return -1; return -1;
} }
@@ -1073,12 +1140,16 @@ int Toy_private_set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
Toy_Literal val = arguments->literals[2]; Toy_Literal val = arguments->literals[2];
if (!TOY_IS_IDENTIFIER(idn)) { if (!TOY_IS_IDENTIFIER(idn)) {
interpreter->errorOutput("Expected identifier in _set\n"); interpreter->errorOutput("Expected identifier in set\n");
return -1; return -1;
} }
Toy_parseIdentifierToValue(interpreter, &obj); Toy_parseIdentifierToValue(interpreter, &obj);
if (TOY_IS_IDENTIFIER(obj)) {
return -1;
}
bool freeKey = false; bool freeKey = false;
if (TOY_IS_IDENTIFIER(key)) { if (TOY_IS_IDENTIFIER(key)) {
Toy_parseIdentifierToValue(interpreter, &key); Toy_parseIdentifierToValue(interpreter, &key);
@@ -1091,26 +1162,40 @@ int Toy_private_set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
freeVal = true; freeVal = true;
} }
if (TOY_IS_IDENTIFIER(key) || TOY_IS_IDENTIFIER(val)) {
if (freeKey) {
Toy_freeLiteral(key);
}
if (freeVal) {
Toy_freeLiteral(val);
}
return -1;
}
switch(obj.type) { switch(obj.type) {
case TOY_LITERAL_ARRAY: { case TOY_LITERAL_ARRAY: {
Toy_Literal typeLiteral = Toy_getScopeType(interpreter->scope, key); //check the subtype of the array, if there is one, against the given argument
Toy_Literal typeLiteral = Toy_getScopeType(interpreter->scope, idn);
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_ARRAY) { if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_ARRAY) {
Toy_Literal subtypeLiteral = ((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0]; Toy_Literal subtypeLiteral = ((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0];
if (TOY_AS_TYPE(subtypeLiteral).typeOf != TOY_LITERAL_ANY && TOY_AS_TYPE(subtypeLiteral).typeOf != val.type) { if (TOY_AS_TYPE(subtypeLiteral).typeOf != TOY_LITERAL_ANY && TOY_AS_TYPE(subtypeLiteral).typeOf != val.type) {
interpreter->errorOutput("Bad argument type in _set\n"); interpreter->errorOutput("Bad argument type in set\n");
Toy_freeLiteral(typeLiteral);
return -1; return -1;
} }
} }
Toy_freeLiteral(typeLiteral);
if (!TOY_IS_INTEGER(key)) { if (!TOY_IS_INTEGER(key)) {
interpreter->errorOutput("Expected integer index in _set\n"); interpreter->errorOutput("Expected integer index in set\n");
return -1; return -1;
} }
if (TOY_AS_ARRAY(obj)->count <= TOY_AS_INTEGER(key) || TOY_AS_INTEGER(key) < 0) { if (TOY_AS_INTEGER(key) >= TOY_AS_ARRAY(obj)->count || TOY_AS_INTEGER(key) < 0) {
interpreter->errorOutput("Index out of bounds in _set\n"); interpreter->errorOutput("Index out of bounds in set\n");
return -1; return -1;
} }
@@ -1119,7 +1204,7 @@ int Toy_private_set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
TOY_AS_ARRAY(obj)->literals[TOY_AS_INTEGER(key)] = Toy_copyLiteral(val); TOY_AS_ARRAY(obj)->literals[TOY_AS_INTEGER(key)] = Toy_copyLiteral(val);
if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) {
interpreter->errorOutput("Incorrect type assigned to array in _set: \""); interpreter->errorOutput("Incorrect type assigned to array in set: \"");
Toy_printLiteralCustom(val, interpreter->errorOutput); Toy_printLiteralCustom(val, interpreter->errorOutput);
interpreter->errorOutput("\"\n"); interpreter->errorOutput("\"\n");
return -1; return -1;
@@ -1136,12 +1221,12 @@ int Toy_private_set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
Toy_Literal valSubtypeLiteral = ((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[1]; Toy_Literal valSubtypeLiteral = ((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[1];
if (TOY_AS_TYPE(keySubtypeLiteral).typeOf != TOY_LITERAL_ANY && TOY_AS_TYPE(keySubtypeLiteral).typeOf != key.type) { if (TOY_AS_TYPE(keySubtypeLiteral).typeOf != TOY_LITERAL_ANY && TOY_AS_TYPE(keySubtypeLiteral).typeOf != key.type) {
interpreter->printOutput("bad argument type in _set\n"); interpreter->printOutput("bad argument type in set\n");
return -1; return -1;
} }
if (TOY_AS_TYPE(valSubtypeLiteral).typeOf != TOY_LITERAL_ANY && TOY_AS_TYPE(valSubtypeLiteral).typeOf != val.type) { if (TOY_AS_TYPE(valSubtypeLiteral).typeOf != TOY_LITERAL_ANY && TOY_AS_TYPE(valSubtypeLiteral).typeOf != val.type) {
interpreter->printOutput("bad argument type in _set\n"); interpreter->printOutput("bad argument type in set\n");
return -1; return -1;
} }
} }
@@ -1149,7 +1234,7 @@ int Toy_private_set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
Toy_setLiteralDictionary(TOY_AS_DICTIONARY(obj), key, val); Toy_setLiteralDictionary(TOY_AS_DICTIONARY(obj), key, val);
if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) {
interpreter->errorOutput("Incorrect type assigned to dictionary in _set: \""); interpreter->errorOutput("Incorrect type assigned to dictionary in set: \"");
Toy_printLiteralCustom(val, interpreter->errorOutput); Toy_printLiteralCustom(val, interpreter->errorOutput);
interpreter->errorOutput("\"\n"); interpreter->errorOutput("\"\n");
return -1; return -1;
@@ -1159,7 +1244,7 @@ int Toy_private_set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
} }
default: default:
interpreter->errorOutput("Incorrect compound type in _set: "); interpreter->errorOutput("Incorrect compound type in set: ");
Toy_printLiteralCustom(obj, interpreter->errorOutput); Toy_printLiteralCustom(obj, interpreter->errorOutput);
interpreter->errorOutput("\"\n"); interpreter->errorOutput("\"\n");
return -1; return -1;
@@ -1181,7 +1266,7 @@ int Toy_private_set(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
int Toy_private_get(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { int Toy_private_get(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//if wrong number of arguments, fail //if wrong number of arguments, fail
if (arguments->count != 2) { if (arguments->count != 2) {
interpreter->errorOutput("Incorrect number of arguments to _get"); interpreter->errorOutput("Incorrect number of arguments to get");
return -1; return -1;
} }
@@ -1200,15 +1285,25 @@ int Toy_private_get(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
freeKey = true; freeKey = true;
} }
switch(obj.type) { if (TOY_IS_IDENTIFIER(obj) || TOY_IS_IDENTIFIER(key)) {
case TOY_LITERAL_ARRAY: { if (freeObj) {
if (!TOY_IS_INTEGER(key)) { Toy_freeLiteral(obj);
interpreter->errorOutput("Expected integer index in _get\n"); }
if (freeKey) {
Toy_freeLiteral(key);
}
return -1; return -1;
} }
if (TOY_AS_ARRAY(obj)->count <= TOY_AS_INTEGER(key) || TOY_AS_INTEGER(key) < 0) { switch(obj.type) {
interpreter->errorOutput("Index out of bounds in _get\n"); case TOY_LITERAL_ARRAY: {
if (!TOY_IS_INTEGER(key)) {
interpreter->errorOutput("Expected integer index in get\n");
return -1;
}
if (TOY_AS_INTEGER(key) >= TOY_AS_ARRAY(obj)->count || TOY_AS_INTEGER(key) < 0) {
interpreter->errorOutput("Index out of bounds in get\n");
return -1; return -1;
} }
@@ -1242,7 +1337,7 @@ int Toy_private_get(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
} }
default: default:
interpreter->errorOutput("Incorrect compound type in _get \""); interpreter->errorOutput("Incorrect compound type in get \"");
Toy_printLiteralCustom(obj, interpreter->errorOutput); Toy_printLiteralCustom(obj, interpreter->errorOutput);
interpreter->errorOutput("\"\n"); interpreter->errorOutput("\"\n");
return -1; return -1;
@@ -1252,7 +1347,7 @@ int Toy_private_get(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
int Toy_private_push(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { int Toy_private_push(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//if wrong number of arguments, fail //if wrong number of arguments, fail
if (arguments->count != 2) { if (arguments->count != 2) {
interpreter->errorOutput("Incorrect number of arguments to _push\n"); interpreter->errorOutput("Incorrect number of arguments to push\n");
return -1; return -1;
} }
@@ -1261,35 +1356,47 @@ int Toy_private_push(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_Literal val = arguments->literals[1]; Toy_Literal val = arguments->literals[1];
if (!TOY_IS_IDENTIFIER(idn)) { if (!TOY_IS_IDENTIFIER(idn)) {
interpreter->errorOutput("Expected identifier in _push\n"); interpreter->errorOutput("Expected identifier in push\n");
return -1; return -1;
} }
Toy_parseIdentifierToValue(interpreter, &obj); Toy_parseIdentifierToValue(interpreter, &obj);
if (TOY_IS_IDENTIFIER(obj)) {
return -1;
}
bool freeVal = false; bool freeVal = false;
if (TOY_IS_IDENTIFIER(val)) { if (TOY_IS_IDENTIFIER(val)) {
Toy_parseIdentifierToValue(interpreter, &val); Toy_parseIdentifierToValue(interpreter, &val);
freeVal = true; freeVal = true;
} }
if (TOY_IS_IDENTIFIER(val)) {
return -1;
}
switch(obj.type) { switch(obj.type) {
case TOY_LITERAL_ARRAY: { case TOY_LITERAL_ARRAY: {
Toy_Literal typeLiteral = Toy_getScopeType(interpreter->scope, val); //check the subtype of the array, if there is one, against the given argument
Toy_Literal typeLiteral = Toy_getScopeType(interpreter->scope, idn);
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_ARRAY) { if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_ARRAY) {
Toy_Literal subtypeLiteral = ((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0]; Toy_Literal subtypeLiteral = ((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0];
if (TOY_AS_TYPE(subtypeLiteral).typeOf != TOY_LITERAL_ANY && TOY_AS_TYPE(subtypeLiteral).typeOf != val.type) { if (TOY_AS_TYPE(subtypeLiteral).typeOf != TOY_LITERAL_ANY && TOY_AS_TYPE(subtypeLiteral).typeOf != val.type) {
interpreter->errorOutput("Bad argument type in _push"); interpreter->errorOutput("Bad argument type in push");
Toy_freeLiteral(typeLiteral);
return -1; return -1;
} }
} }
Toy_freeLiteral(typeLiteral);
Toy_pushLiteralArray(TOY_AS_ARRAY(obj), val); Toy_pushLiteralArray(TOY_AS_ARRAY(obj), val);
if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { //TODO: could definitely be more efficient than overwriting the whole original object if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { //TODO: could definitely be more efficient than overwriting the whole original object
interpreter->errorOutput("Incorrect type assigned to array in _push: \""); interpreter->errorOutput("Incorrect type assigned to array in push: \"");
Toy_printLiteralCustom(val, interpreter->errorOutput); Toy_printLiteralCustom(val, interpreter->errorOutput);
interpreter->errorOutput("\"\n"); interpreter->errorOutput("\"\n");
return -1; return -1;
@@ -1305,7 +1412,7 @@ int Toy_private_push(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
} }
default: default:
interpreter->errorOutput("Incorrect compound type in _push: "); interpreter->errorOutput("Incorrect compound type in push: ");
Toy_printLiteralCustom(obj, interpreter->errorOutput); Toy_printLiteralCustom(obj, interpreter->errorOutput);
interpreter->errorOutput("\n"); interpreter->errorOutput("\n");
return -1; return -1;
@@ -1315,7 +1422,7 @@ int Toy_private_push(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
int Toy_private_pop(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { int Toy_private_pop(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//if wrong number of arguments, fail //if wrong number of arguments, fail
if (arguments->count != 1) { if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments to _pop\n"); interpreter->errorOutput("Incorrect number of arguments to pop\n");
return -1; return -1;
} }
@@ -1323,12 +1430,16 @@ int Toy_private_pop(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
Toy_Literal obj = arguments->literals[0]; Toy_Literal obj = arguments->literals[0];
if (!TOY_IS_IDENTIFIER(idn)) { if (!TOY_IS_IDENTIFIER(idn)) {
interpreter->errorOutput("Expected identifier in _pop\n"); interpreter->errorOutput("Expected identifier in pop\n");
return -1; return -1;
} }
Toy_parseIdentifierToValue(interpreter, &obj); Toy_parseIdentifierToValue(interpreter, &obj);
if (TOY_IS_IDENTIFIER(obj)) {
return -1;
}
switch(obj.type) { switch(obj.type) {
case TOY_LITERAL_ARRAY: { case TOY_LITERAL_ARRAY: {
Toy_Literal lit = Toy_popLiteralArray(TOY_AS_ARRAY(obj)); Toy_Literal lit = Toy_popLiteralArray(TOY_AS_ARRAY(obj));
@@ -1336,7 +1447,7 @@ int Toy_private_pop(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
Toy_freeLiteral(lit); Toy_freeLiteral(lit);
if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { //TODO: could definitely be more efficient than overwriting the whole original object if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { //TODO: could definitely be more efficient than overwriting the whole original object
interpreter->errorOutput("Incorrect type assigned to array in _pop: "); interpreter->errorOutput("Incorrect type assigned to array in pop: ");
Toy_printLiteralCustom(obj, interpreter->errorOutput); Toy_printLiteralCustom(obj, interpreter->errorOutput);
interpreter->errorOutput("\n"); interpreter->errorOutput("\n");
return -1; return -1;
@@ -1348,7 +1459,7 @@ int Toy_private_pop(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
} }
default: default:
interpreter->errorOutput("Incorrect compound type in _pop: "); interpreter->errorOutput("Incorrect compound type in pop: ");
Toy_printLiteralCustom(obj, interpreter->errorOutput); Toy_printLiteralCustom(obj, interpreter->errorOutput);
interpreter->errorOutput("\n"); interpreter->errorOutput("\n");
return -1; return -1;
@@ -1358,7 +1469,7 @@ int Toy_private_pop(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
int Toy_private_length(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { int Toy_private_length(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//if wrong number of arguments, fail //if wrong number of arguments, fail
if (arguments->count != 1) { if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments to _length\n"); interpreter->errorOutput("Incorrect number of arguments to length\n");
return -1; return -1;
} }
@@ -1370,6 +1481,10 @@ int Toy_private_length(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments
freeObj = true; freeObj = true;
} }
if (TOY_IS_IDENTIFIER(obj)) {
return -1;
}
switch(obj.type) { switch(obj.type) {
case TOY_LITERAL_ARRAY: { case TOY_LITERAL_ARRAY: {
Toy_Literal lit = TOY_TO_INTEGER_LITERAL( TOY_AS_ARRAY(obj)->count ); Toy_Literal lit = TOY_TO_INTEGER_LITERAL( TOY_AS_ARRAY(obj)->count );
@@ -1393,7 +1508,7 @@ int Toy_private_length(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments
} }
default: default:
interpreter->errorOutput("Incorrect compound type in _length: "); interpreter->errorOutput("Incorrect compound type in length: ");
Toy_printLiteralCustom(obj, interpreter->errorOutput); Toy_printLiteralCustom(obj, interpreter->errorOutput);
interpreter->errorOutput("\n"); interpreter->errorOutput("\n");
return -1; return -1;
@@ -1409,7 +1524,7 @@ int Toy_private_length(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments
int Toy_private_clear(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { int Toy_private_clear(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
//if wrong number of arguments, fail //if wrong number of arguments, fail
if (arguments->count != 1) { if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments to _clear\n"); interpreter->errorOutput("Incorrect number of arguments to clear\n");
return -1; return -1;
} }
@@ -1417,12 +1532,16 @@ int Toy_private_clear(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_Literal obj = arguments->literals[0]; Toy_Literal obj = arguments->literals[0];
if (!TOY_IS_IDENTIFIER(idn)) { if (!TOY_IS_IDENTIFIER(idn)) {
interpreter->errorOutput("expected identifier in _clear\n"); interpreter->errorOutput("expected identifier in clear\n");
return -1; return -1;
} }
Toy_parseIdentifierToValue(interpreter, &obj); Toy_parseIdentifierToValue(interpreter, &obj);
if (TOY_IS_IDENTIFIER(obj)) {
return -1;
}
//NOTE: just pass in new compounds //NOTE: just pass in new compounds
switch(obj.type) { switch(obj.type) {
@@ -1433,7 +1552,7 @@ int Toy_private_clear(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_Literal obj = TOY_TO_ARRAY_LITERAL(array); Toy_Literal obj = TOY_TO_ARRAY_LITERAL(array);
if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) {
interpreter->errorOutput("Incorrect type assigned to array in _clear: "); interpreter->errorOutput("Incorrect type assigned to array in clear: ");
Toy_printLiteralCustom(obj, interpreter->errorOutput); Toy_printLiteralCustom(obj, interpreter->errorOutput);
interpreter->errorOutput("\n"); interpreter->errorOutput("\n");
return -1; return -1;
@@ -1451,7 +1570,7 @@ int Toy_private_clear(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
Toy_Literal obj = TOY_TO_DICTIONARY_LITERAL(dictionary); Toy_Literal obj = TOY_TO_DICTIONARY_LITERAL(dictionary);
if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) { if (!Toy_setScopeVariable(interpreter->scope, idn, obj, true)) {
interpreter->errorOutput("Incorrect type assigned to dictionary in _clear: "); interpreter->errorOutput("Incorrect type assigned to dictionary in clear: ");
Toy_printLiteralCustom(obj, interpreter->errorOutput); Toy_printLiteralCustom(obj, interpreter->errorOutput);
interpreter->errorOutput("\n"); interpreter->errorOutput("\n");
return -1; return -1;
@@ -1463,7 +1582,7 @@ int Toy_private_clear(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
} }
default: default:
interpreter->errorOutput("Incorrect compound type in _clear: "); interpreter->errorOutput("Incorrect compound type in clear: ");
Toy_printLiteralCustom(obj, interpreter->errorOutput); Toy_printLiteralCustom(obj, interpreter->errorOutput);
interpreter->errorOutput("\n"); interpreter->errorOutput("\n");
return -1; return -1;
+23 -25
View File
@@ -15,23 +15,22 @@ STATIC_ASSERT(sizeof(unsigned char) == 1);
STATIC_ASSERT(sizeof(unsigned short) == 2); STATIC_ASSERT(sizeof(unsigned short) == 2);
STATIC_ASSERT(sizeof(unsigned int) == 4); STATIC_ASSERT(sizeof(unsigned int) == 4);
//declare the singleton //declare the singleton with default values
Toy_CommandLine Toy_commandLine; Toy_CommandLine Toy_commandLine = {
.error = false,
.help = false,
.version = false,
.binaryfile = NULL,
.sourcefile = NULL,
.compilefile = NULL,
.outfile = "out.tb",
.source = NULL,
.initialfile = NULL,
.enablePrintNewline = true,
.verbose = false
};
void Toy_initCommandLine(int argc, const char* argv[]) { void Toy_initCommandLine(int argc, const char* argv[]) {
//default values
Toy_commandLine.error = false;
Toy_commandLine.help = false;
Toy_commandLine.version = false;
Toy_commandLine.binaryfile = NULL;
Toy_commandLine.sourcefile = NULL;
Toy_commandLine.compilefile = NULL;
Toy_commandLine.outfile = "out.tb";
Toy_commandLine.source = NULL;
Toy_commandLine.initialfile = NULL;
Toy_commandLine.enablePrintNewline = true;
Toy_commandLine.verbose = false;
for (int i = 1; i < argc; i++) { //start at 1 to skip the program name for (int i = 1; i < argc; i++) { //start at 1 to skip the program name
Toy_commandLine.error = true; //error state by default, set to false by successful flags Toy_commandLine.error = true; //error state by default, set to false by successful flags
@@ -115,16 +114,15 @@ void Toy_usageCommandLine(int argc, const char* argv[]) {
void Toy_helpCommandLine(int argc, const char* argv[]) { void Toy_helpCommandLine(int argc, const char* argv[]) {
Toy_usageCommandLine(argc, argv); Toy_usageCommandLine(argc, argv);
printf("<file.tb>\t\t\tBinary input file in tb format, must be version %d.%d.%d.\n\n", TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH); printf(" -h, --help\t\t\tShow this help then exit.\n");
printf("-h\t| --help\t\tShow this help then exit.\n\n"); printf(" -v, --version\t\t\tShow version and copyright information then exit.\n");
printf("-v\t| --version\t\tShow version and copyright information then exit.\n\n"); printf(" -d, --debug\t\t\tBe verbose when operating.\n");
printf("-d\t| --debug\t\tBe verbose when operating.\n\n"); printf(" -f, --file filename\t\tParse, compile and execute the source file.\n");
printf("-f\t| --file filename\tParse, compile and execute the source file.\n\n"); printf(" -i, --input source\t\tParse, compile and execute this given string of source code.\n");
printf("-i\t| --input source\tParse, compile and execute this given string of source code.\n\n"); printf(" -c, --compile filename\tParse and compile the specified source file into an output file.\n");
printf("-c\t| --compile filename\tParse and compile the specified source file into an output file.\n\n"); printf(" -o, --output outfile\t\tName of the output file built with --compile (default: out.tb).\n");
printf("-o\t| --output outfile\tName of the output file built with --compile (default: out.tb).\n\n"); printf(" -t, --initial filename\tStart the repl as normal, after first running the given file.\n");
printf("-t\t| --initial filename\tStart the repl as normal, after first running the given file.\n\n"); printf(" -n\t\t\t\tDisable the newline character at the end of the print statement.\n");
printf("-n\t|\t\t\tDisable the newline character at the end of the print statement.\n\n");
} }
void Toy_copyrightCommandLine(int argc, const char* argv[]) { void Toy_copyrightCommandLine(int argc, const char* argv[]) {
+4 -3
View File
@@ -4,9 +4,9 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#define TOY_VERSION_MAJOR 0 #define TOY_VERSION_MAJOR 1
#define TOY_VERSION_MINOR 9 #define TOY_VERSION_MINOR 0
#define TOY_VERSION_PATCH 0 #define TOY_VERSION_PATCH 1
#define TOY_VERSION_BUILD __DATE__ " " __TIME__ #define TOY_VERSION_BUILD __DATE__ " " __TIME__
//platform/compiler-specific instructions //platform/compiler-specific instructions
@@ -43,6 +43,7 @@ typedef struct {
bool verbose; bool verbose;
} Toy_CommandLine; } Toy_CommandLine;
//these are intended for the repl only, despite using the api prefix
TOY_API Toy_CommandLine Toy_commandLine; TOY_API Toy_CommandLine Toy_commandLine;
TOY_API void Toy_initCommandLine(int argc, const char* argv[]); TOY_API void Toy_initCommandLine(int argc, const char* argv[]);
+8 -4
View File
@@ -9,6 +9,7 @@
#include "toy_console_colors.h" #include "toy_console_colors.h"
#include <stdio.h> #include <stdio.h>
#include <string.h>
void Toy_initCompiler(Toy_Compiler* compiler) { void Toy_initCompiler(Toy_Compiler* compiler) {
Toy_initLiteralArray(&compiler->literalCache); Toy_initLiteralArray(&compiler->literalCache);
@@ -981,6 +982,8 @@ void Toy_writeCompiler(Toy_Compiler* compiler, Toy_ASTNode* node) {
if (op != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy if (op != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy
compiler->bytecode[compiler->count++] = (unsigned char)op; //1 byte compiler->bytecode[compiler->count++] = (unsigned char)op; //1 byte
} }
//TODO: could free up AST Nodes
} }
void Toy_freeCompiler(Toy_Compiler* compiler) { void Toy_freeCompiler(Toy_Compiler* compiler) {
@@ -989,6 +992,7 @@ void Toy_freeCompiler(Toy_Compiler* compiler) {
compiler->bytecode = NULL; compiler->bytecode = NULL;
compiler->capacity = 0; compiler->capacity = 0;
compiler->count = 0; compiler->count = 0;
compiler->panic = false;
} }
static void emitByte(unsigned char** collationPtr, int* capacityPtr, int* countPtr, unsigned char byte) { static void emitByte(unsigned char** collationPtr, int* capacityPtr, int* countPtr, unsigned char byte) {
@@ -1036,7 +1040,7 @@ static void emitFloat(unsigned char** collationPtr, int* capacityPtr, int* count
} }
//return the result //return the result
static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size, bool embedHeader) { static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, size_t* size, bool embedHeader) {
if (compiler->panic) { if (compiler->panic) {
fprintf(stderr, TOY_CC_ERROR "[internal] Can't collate a panicked compiler\n" TOY_CC_RESET); fprintf(stderr, TOY_CC_ERROR "[internal] Can't collate a panicked compiler\n" TOY_CC_RESET);
return NULL; return NULL;
@@ -1181,14 +1185,14 @@ static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size
void* fnCompiler = TOY_AS_FUNCTION(fn).inner.bytecode; //store the compiler here for now void* fnCompiler = TOY_AS_FUNCTION(fn).inner.bytecode; //store the compiler here for now
//collate the function into bytecode (without header) //collate the function into bytecode (without header)
int size = 0; size_t size = 0;
unsigned char* bytes = collateCompilerHeaderOpt((Toy_Compiler*)fnCompiler, &size, false); unsigned char* bytes = collateCompilerHeaderOpt((Toy_Compiler*)fnCompiler, &size, false);
//emit how long this section is, +1 for ending mark //emit how long this section is, +1 for ending mark
Toy_emitShort(&fnCollation, &fnCapacity, &fnCount, (unsigned short)size + 1); Toy_emitShort(&fnCollation, &fnCapacity, &fnCount, (unsigned short)size + 1);
//write the fn to the fn collation //write the fn to the fn collation
for (int i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
emitByte(&fnCollation, &fnCapacity, &fnCount, bytes[i]); emitByte(&fnCollation, &fnCapacity, &fnCount, bytes[i]);
} }
@@ -1296,6 +1300,6 @@ static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, int* size
} }
//the whole point of the compiler is to alter bytecode, so leave it as non-const //the whole point of the compiler is to alter bytecode, so leave it as non-const
unsigned char* Toy_collateCompiler(Toy_Compiler* compiler, int* size) { unsigned char* Toy_collateCompiler(Toy_Compiler* compiler, size_t* size) {
return collateCompilerHeaderOpt(compiler, size, true); return collateCompilerHeaderOpt(compiler, size, true);
} }
+1 -1
View File
@@ -19,4 +19,4 @@ TOY_API void Toy_writeCompiler(Toy_Compiler* compiler, Toy_ASTNode* node);
TOY_API void Toy_freeCompiler(Toy_Compiler* compiler); TOY_API void Toy_freeCompiler(Toy_Compiler* compiler);
//embed the header, data section, code section, function section, etc. //embed the header, data section, code section, function section, etc.
TOY_API unsigned char* Toy_collateCompiler(Toy_Compiler* compiler, int* size); TOY_API unsigned char* Toy_collateCompiler(Toy_Compiler* compiler, size_t* size);
+150 -7
View File
@@ -21,9 +21,7 @@ static void printWrapper(const char* output) {
} }
static void assertWrapper(const char* output) { static void assertWrapper(const char* output) {
fprintf(stderr, TOY_CC_ERROR "Assertion failure: "); fprintf(stderr, TOY_CC_ERROR "Assertion failure: %s\n" TOY_CC_RESET, output);
fprintf(stderr, "%s", output);
fprintf(stderr, "\n" TOY_CC_RESET); //default new line
} }
static void errorWrapper(const char* output) { static void errorWrapper(const char* output) {
@@ -37,8 +35,7 @@ bool Toy_injectNativeFn(Toy_Interpreter* interpreter, const char* name, Toy_Nati
return false; return false;
} }
int identifierLength = strlen(name); Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString(name));
Toy_Literal identifier = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefStringLength(name, identifierLength));
//make sure the name isn't taken //make sure the name isn't taken
if (Toy_existsLiteralDictionary(&interpreter->scope->variables, identifier)) { if (Toy_existsLiteralDictionary(&interpreter->scope->variables, identifier)) {
@@ -234,6 +231,12 @@ static bool execAssert(Toy_Interpreter* interpreter) {
Toy_freeLiteral(lhsIdn); Toy_freeLiteral(lhsIdn);
} }
if (TOY_IS_IDENTIFIER(lhs)) {
Toy_freeLiteral(lhs);
Toy_freeLiteral(rhs);
return false;
}
if (!TOY_IS_STRING(rhs)) { if (!TOY_IS_STRING(rhs)) {
interpreter->errorOutput("The assert keyword needs a string as the second argument, received: "); interpreter->errorOutput("The assert keyword needs a string as the second argument, received: ");
Toy_printLiteralCustom(rhs, interpreter->errorOutput); Toy_printLiteralCustom(rhs, interpreter->errorOutput);
@@ -268,6 +271,11 @@ static bool execPrint(Toy_Interpreter* interpreter) {
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(lit)) {
Toy_freeLiteral(lit);
return false;
}
Toy_printLiteralCustom(lit, interpreter->printOutput); Toy_printLiteralCustom(lit, interpreter->printOutput);
Toy_freeLiteral(lit); Toy_freeLiteral(lit);
@@ -300,6 +308,11 @@ static bool rawLiteral(Toy_Interpreter* interpreter) {
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(lit)) {
Toy_freeLiteral(lit);
return false;
}
Toy_pushLiteralArray(&interpreter->stack, lit); Toy_pushLiteralArray(&interpreter->stack, lit);
Toy_freeLiteral(lit); Toy_freeLiteral(lit);
@@ -315,6 +328,11 @@ static bool execNegate(Toy_Interpreter* interpreter) {
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(lit)) {
Toy_freeLiteral(lit);
return false;
}
if (TOY_IS_INTEGER(lit)) { if (TOY_IS_INTEGER(lit)) {
lit = TOY_TO_INTEGER_LITERAL(-TOY_AS_INTEGER(lit)); lit = TOY_TO_INTEGER_LITERAL(-TOY_AS_INTEGER(lit));
} }
@@ -346,6 +364,11 @@ static bool execInvert(Toy_Interpreter* interpreter) {
Toy_freeLiteral(idn); Toy_freeLiteral(idn);
} }
if (TOY_IS_IDENTIFIER(lit)) {
Toy_freeLiteral(lit);
return false;
}
if (TOY_IS_BOOLEAN(lit)) { if (TOY_IS_BOOLEAN(lit)) {
lit = TOY_TO_BOOLEAN_LITERAL(!TOY_AS_BOOLEAN(lit)); lit = TOY_TO_BOOLEAN_LITERAL(!TOY_AS_BOOLEAN(lit));
} }
@@ -379,6 +402,12 @@ static bool execArithmetic(Toy_Interpreter* interpreter, Toy_Opcode opcode) {
Toy_freeLiteral(lhsIdn); Toy_freeLiteral(lhsIdn);
} }
if (TOY_IS_IDENTIFIER(lhs) || TOY_IS_IDENTIFIER(rhs)) {
Toy_freeLiteral(lhs);
Toy_freeLiteral(rhs);
return false;
}
//special case for string concatenation ONLY //special case for string concatenation ONLY
if (TOY_IS_STRING(lhs) && TOY_IS_STRING(rhs) && (opcode == TOY_OP_ADDITION || opcode == TOY_OP_VAR_ADDITION_ASSIGN)) { if (TOY_IS_STRING(lhs) && TOY_IS_STRING(rhs) && (opcode == TOY_OP_ADDITION || opcode == TOY_OP_VAR_ADDITION_ASSIGN)) {
//check for overflow //check for overflow
@@ -511,6 +540,10 @@ static Toy_Literal parseTypeToValue(Toy_Interpreter* interpreter, Toy_Literal ty
Toy_freeLiteral(typeIdn); Toy_freeLiteral(typeIdn);
} }
if (TOY_IS_IDENTIFIER(type)) {
return TOY_TO_NULL_LITERAL;
}
//if this is an array or dictionary, continue to the subtypes //if this is an array or dictionary, continue to the subtypes
if (TOY_IS_TYPE(type) && (TOY_AS_TYPE(type).typeOf == TOY_LITERAL_ARRAY || TOY_AS_TYPE(type).typeOf == TOY_LITERAL_DICTIONARY)) { if (TOY_IS_TYPE(type) && (TOY_AS_TYPE(type).typeOf == TOY_LITERAL_ARRAY || TOY_AS_TYPE(type).typeOf == TOY_LITERAL_DICTIONARY)) {
for (int i = 0; i < TOY_AS_TYPE(type).count; i++) { for (int i = 0; i < TOY_AS_TYPE(type).count; i++) {
@@ -551,6 +584,12 @@ static bool execVarDecl(Toy_Interpreter* interpreter, bool lng) {
Toy_freeLiteral(typeIdn); Toy_freeLiteral(typeIdn);
} }
if (TOY_IS_IDENTIFIER(type)) {
Toy_freeLiteral(identifier);
Toy_freeLiteral(type);
return false;
}
//BUGFIX: because identifiers are getting embedded in type definitions //BUGFIX: because identifiers are getting embedded in type definitions
type = parseTypeToValue(interpreter, type); type = parseTypeToValue(interpreter, type);
@@ -568,6 +607,13 @@ static bool execVarDecl(Toy_Interpreter* interpreter, bool lng) {
Toy_freeLiteral(valIdn); Toy_freeLiteral(valIdn);
} }
if (TOY_IS_IDENTIFIER(val)) {
Toy_freeLiteral(identifier);
Toy_freeLiteral(type);
Toy_freeLiteral(val);
return false;
}
if (TOY_IS_ARRAY(val) || TOY_IS_DICTIONARY(val)) { if (TOY_IS_ARRAY(val) || TOY_IS_DICTIONARY(val)) {
Toy_parseCompoundToPureValues(interpreter, &val); Toy_parseCompoundToPureValues(interpreter, &val);
} }
@@ -648,6 +694,12 @@ static bool execVarAssign(Toy_Interpreter* interpreter) {
Toy_freeLiteral(rhsIdn); Toy_freeLiteral(rhsIdn);
} }
if (TOY_IS_IDENTIFIER(rhs)) {
Toy_freeLiteral(lhs);
Toy_freeLiteral(rhs);
return false;
}
if (TOY_IS_ARRAY(rhs) || TOY_IS_DICTIONARY(rhs)) { if (TOY_IS_ARRAY(rhs) || TOY_IS_DICTIONARY(rhs)) {
Toy_parseCompoundToPureValues(interpreter, &rhs); Toy_parseCompoundToPureValues(interpreter, &rhs);
} }
@@ -717,6 +769,12 @@ static bool execValCast(Toy_Interpreter* interpreter) {
Toy_freeLiteral(valueIdn); Toy_freeLiteral(valueIdn);
} }
if (TOY_IS_IDENTIFIER(value)) {
Toy_freeLiteral(type);
Toy_freeLiteral(value);
return false;
}
Toy_Literal result = TOY_TO_NULL_LITERAL; Toy_Literal result = TOY_TO_NULL_LITERAL;
if (TOY_IS_NULL(value)) { if (TOY_IS_NULL(value)) {
@@ -851,6 +909,12 @@ static bool execCompareEqual(Toy_Interpreter* interpreter, bool invert) {
Toy_freeLiteral(lhsIdn); Toy_freeLiteral(lhsIdn);
} }
if (TOY_IS_IDENTIFIER(lhs) || TOY_IS_IDENTIFIER(rhs)) {
Toy_freeLiteral(lhs);
Toy_freeLiteral(rhs);
return false;
}
bool result = Toy_literalsAreEqual(lhs, rhs); bool result = Toy_literalsAreEqual(lhs, rhs);
if (invert) { if (invert) {
@@ -879,6 +943,12 @@ static bool execCompareLess(Toy_Interpreter* interpreter, bool invert) {
Toy_freeLiteral(lhsIdn); Toy_freeLiteral(lhsIdn);
} }
if (TOY_IS_IDENTIFIER(lhs) || TOY_IS_IDENTIFIER(rhs)) {
Toy_freeLiteral(lhs);
Toy_freeLiteral(rhs);
return false;
}
//not a number, return falure //not a number, return falure
if (!(TOY_IS_INTEGER(lhs) || TOY_IS_FLOAT(lhs))) { if (!(TOY_IS_INTEGER(lhs) || TOY_IS_FLOAT(lhs))) {
interpreter->errorOutput("Incorrect type in comparison, value \""); interpreter->errorOutput("Incorrect type in comparison, value \"");
@@ -939,6 +1009,12 @@ static bool execCompareLessEqual(Toy_Interpreter* interpreter, bool invert) {
Toy_freeLiteral(lhsIdn); Toy_freeLiteral(lhsIdn);
} }
if (TOY_IS_IDENTIFIER(lhs) || TOY_IS_IDENTIFIER(rhs)) {
Toy_freeLiteral(lhs);
Toy_freeLiteral(rhs);
return false;
}
//not a number, return falure //not a number, return falure
if (!(TOY_IS_INTEGER(lhs) || TOY_IS_FLOAT(lhs))) { if (!(TOY_IS_INTEGER(lhs) || TOY_IS_FLOAT(lhs))) {
interpreter->errorOutput("Incorrect type in comparison, value \""); interpreter->errorOutput("Incorrect type in comparison, value \"");
@@ -1000,6 +1076,12 @@ static bool execAnd(Toy_Interpreter* interpreter) {
Toy_freeLiteral(lhsIdn); Toy_freeLiteral(lhsIdn);
} }
if (TOY_IS_IDENTIFIER(lhs) || TOY_IS_IDENTIFIER(rhs)) {
Toy_freeLiteral(lhs);
Toy_freeLiteral(rhs);
return false;
}
if (TOY_IS_TRUTHY(lhs) && TOY_IS_TRUTHY(rhs)) { if (TOY_IS_TRUTHY(lhs) && TOY_IS_TRUTHY(rhs)) {
Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(true)); Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(true));
} }
@@ -1027,6 +1109,12 @@ static bool execOr(Toy_Interpreter* interpreter) {
Toy_freeLiteral(lhsIdn); Toy_freeLiteral(lhsIdn);
} }
if (TOY_IS_IDENTIFIER(lhs) || TOY_IS_IDENTIFIER(rhs)) {
Toy_freeLiteral(lhs);
Toy_freeLiteral(rhs);
return false;
}
if (TOY_IS_TRUTHY(lhs) || TOY_IS_TRUTHY(rhs)) { if (TOY_IS_TRUTHY(lhs) || TOY_IS_TRUTHY(rhs)) {
Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(true)); Toy_pushLiteralArray(&interpreter->stack, TOY_TO_BOOLEAN_LITERAL(true));
} }
@@ -1070,6 +1158,11 @@ static bool execFalseJump(Toy_Interpreter* interpreter) {
Toy_freeLiteral(litIdn); Toy_freeLiteral(litIdn);
} }
if (TOY_IS_IDENTIFIER(lit)) {
Toy_freeLiteral(lit);
return false;
}
if (TOY_IS_NULL(lit)) { if (TOY_IS_NULL(lit)) {
interpreter->errorOutput("Null detected in comparison\n"); interpreter->errorOutput("Null detected in comparison\n");
Toy_freeLiteral(lit); Toy_freeLiteral(lit);
@@ -1180,11 +1273,13 @@ static bool execFnCall(Toy_Interpreter* interpreter, bool looseFirstArgument) {
bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_LiteralArray* arguments, Toy_LiteralArray* returns) { bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_LiteralArray* arguments, Toy_LiteralArray* returns) {
//check for side-loaded native functions //check for side-loaded native functions
if (TOY_IS_FUNCTION_NATIVE(func)) { if (TOY_IS_FUNCTION_NATIVE(func)) {
//TODO: parse out identifier values, see issue #64
//call the native function //call the native function
int returnsCount = TOY_AS_FUNCTION_NATIVE(func)(interpreter, arguments); int returnsCount = TOY_AS_FUNCTION_NATIVE(func)(interpreter, arguments);
if (returnsCount < 0) { if (returnsCount < 0) {
interpreter->errorOutput("Unknown error from native function\n"); // interpreter->errorOutput("Unknown error from native function\n");
return false; return false;
} }
@@ -1288,6 +1383,17 @@ bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_Liter
Toy_freeLiteral(argIdn); Toy_freeLiteral(argIdn);
} }
if (TOY_IS_IDENTIFIER(arg)) {
//free, and skip out
Toy_freeLiteral(arg);
Toy_popScope(inner.scope);
Toy_freeLiteralArray(&inner.stack);
Toy_freeLiteralArray(&inner.literalCache);
return false;
}
if (!Toy_setScopeVariable(inner.scope, paramArray->literals[i], arg, false)) { if (!Toy_setScopeVariable(inner.scope, paramArray->literals[i], arg, false)) {
interpreter->errorOutput("[internal] Could not define parameter (bad type?)\n"); interpreter->errorOutput("[internal] Could not define parameter (bad type?)\n");
@@ -1456,6 +1562,12 @@ static bool execFnReturn(Toy_Interpreter* interpreter) {
Toy_freeLiteral(litIdn); Toy_freeLiteral(litIdn);
} }
if (TOY_IS_IDENTIFIER(lit)) {
Toy_freeLiteralArray(&returns);
Toy_freeLiteral(lit);
return false;
}
if (TOY_IS_ARRAY(lit) || TOY_IS_DICTIONARY(lit)) { if (TOY_IS_ARRAY(lit) || TOY_IS_DICTIONARY(lit)) {
Toy_parseCompoundToPureValues(interpreter, &lit); Toy_parseCompoundToPureValues(interpreter, &lit);
} }
@@ -1527,6 +1639,17 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) {
freeIdn = true; freeIdn = true;
} }
if (TOY_IS_IDENTIFIER(compound)) {
Toy_freeLiteral(third);
Toy_freeLiteral(second);
Toy_freeLiteral(first);
Toy_freeLiteral(compound);
if (freeIdn) {
Toy_freeLiteral(compoundIdn);
}
return true;
}
if (!TOY_IS_ARRAY(compound) && !TOY_IS_DICTIONARY(compound) && !TOY_IS_STRING(compound)) { if (!TOY_IS_ARRAY(compound) && !TOY_IS_DICTIONARY(compound) && !TOY_IS_STRING(compound)) {
interpreter->errorOutput("Unknown compound found in indexing notation: "); interpreter->errorOutput("Unknown compound found in indexing notation: ");
Toy_printLiteralCustom(compound, interpreter->errorOutput); Toy_printLiteralCustom(compound, interpreter->errorOutput);
@@ -1611,12 +1734,33 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) {
Toy_freeLiteral(assignIdn); Toy_freeLiteral(assignIdn);
} }
if (TOY_IS_IDENTIFIER(assign)) {
Toy_freeLiteral(compound);
Toy_freeLiteral(first);
Toy_freeLiteral(second);
Toy_freeLiteral(third);
Toy_freeLiteral(assign);
return false;
}
Toy_Literal compoundIdn = compound; Toy_Literal compoundIdn = compound;
bool freeIdn = false; bool freeIdn = false;
if (TOY_IS_IDENTIFIER(compound) && Toy_parseIdentifierToValue(interpreter, &compound)) { if (TOY_IS_IDENTIFIER(compound) && Toy_parseIdentifierToValue(interpreter, &compound)) {
freeIdn = true; freeIdn = true;
} }
if (TOY_IS_IDENTIFIER(compound)) {
Toy_freeLiteral(compound);
Toy_freeLiteral(first);
Toy_freeLiteral(second);
Toy_freeLiteral(third);
Toy_freeLiteral(assign);
if (freeIdn) {
Toy_freeLiteral(compoundIdn);
}
return false;
}
if (!TOY_IS_ARRAY(compound) && !TOY_IS_DICTIONARY(compound) && !TOY_IS_STRING(compound)) { if (!TOY_IS_ARRAY(compound) && !TOY_IS_DICTIONARY(compound) && !TOY_IS_STRING(compound)) {
interpreter->errorOutput("Unknown compound found in index assigning notation\n"); interpreter->errorOutput("Unknown compound found in index assigning notation\n");
Toy_freeLiteral(assign); Toy_freeLiteral(assign);
@@ -2317,7 +2461,6 @@ static void readInterpreterSections(Toy_Interpreter* interpreter) {
//change the type to normal //change the type to normal
interpreter->literalCache.literals[i] = TOY_TO_FUNCTION_LITERAL(bytes, size); interpreter->literalCache.literals[i] = TOY_TO_FUNCTION_LITERAL(bytes, size);
TOY_AS_FUNCTION(interpreter->literalCache.literals[i]).scope = NULL;
} }
} }
-2
View File
@@ -6,8 +6,6 @@
#include "toy_literal_dictionary.h" #include "toy_literal_dictionary.h"
#include "toy_scope.h" #include "toy_scope.h"
typedef void (*Toy_PrintFn)(const char*);
//the interpreter acts depending on the bytecode instructions //the interpreter acts depending on the bytecode instructions
typedef struct Toy_Interpreter { typedef struct Toy_Interpreter {
//input //input
+8 -8
View File
@@ -117,7 +117,7 @@ static Toy_Token makeErrorToken(Toy_Lexer* lexer, char* msg) {
#ifndef TOY_EXPORT #ifndef TOY_EXPORT
if (Toy_commandLine.verbose) { if (Toy_commandLine.verbose) {
printf("err:"); printf("err:");
Toy_printToken(&token); Toy_private_printToken(&token);
} }
#endif #endif
@@ -136,7 +136,7 @@ static Toy_Token makeToken(Toy_Lexer* lexer, Toy_TokenType type) {
//BUG #10: this shows TOKEN_EOF twice due to the overarching structure of the program - can't be fixed //BUG #10: this shows TOKEN_EOF twice due to the overarching structure of the program - can't be fixed
if (Toy_commandLine.verbose) { if (Toy_commandLine.verbose) {
printf("tok:"); printf("tok:");
Toy_printToken(&token); Toy_private_printToken(&token);
} }
#endif #endif
@@ -168,7 +168,7 @@ static Toy_Token makeIntegerOrFloat(Toy_Lexer* lexer) {
} else { } else {
printf("flt:"); printf("flt:");
} }
Toy_printToken(&token); Toy_private_printToken(&token);
} }
#endif #endif
@@ -221,7 +221,7 @@ static Toy_Token makeString(Toy_Lexer* lexer, char terminator) {
#ifndef TOY_EXPORT #ifndef TOY_EXPORT
if (Toy_commandLine.verbose) { if (Toy_commandLine.verbose) {
printf("str:"); printf("str:");
Toy_printToken(&token); Toy_private_printToken(&token);
} }
#endif #endif
@@ -248,7 +248,7 @@ static Toy_Token makeKeywordOrIdentifier(Toy_Lexer* lexer) {
#ifndef TOY_EXPORT #ifndef TOY_EXPORT
if (Toy_commandLine.verbose) { if (Toy_commandLine.verbose) {
printf("kwd:"); printf("kwd:");
Toy_printToken(&token); Toy_private_printToken(&token);
} }
#endif #endif
@@ -267,7 +267,7 @@ static Toy_Token makeKeywordOrIdentifier(Toy_Lexer* lexer) {
#ifndef TOY_EXPORT #ifndef TOY_EXPORT
if (Toy_commandLine.verbose) { if (Toy_commandLine.verbose) {
printf("idf:"); printf("idf:");
Toy_printToken(&token); Toy_private_printToken(&token);
} }
#endif #endif
@@ -281,7 +281,7 @@ void Toy_initLexer(Toy_Lexer* lexer, const char* source) {
lexer->source = source; lexer->source = source;
} }
Toy_Token Toy_scanLexer(Toy_Lexer* lexer) { Toy_Token Toy_private_scanLexer(Toy_Lexer* lexer) {
eatWhitespace(lexer); eatWhitespace(lexer);
lexer->start = lexer->current; lexer->start = lexer->current;
@@ -352,7 +352,7 @@ static void trim(char** s, int* l) { //all this to remove a newline?
} }
//for debugging //for debugging
void Toy_printToken(Toy_Token* token) { void Toy_private_printToken(Toy_Token* token) {
if (token->type == TOY_TOKEN_ERROR) { if (token->type == TOY_TOKEN_ERROR) {
printf(TOY_CC_ERROR "Error\t%d\t%.*s\n" TOY_CC_RESET, token->line, token->length, token->lexeme); printf(TOY_CC_ERROR "Error\t%d\t%.*s\n" TOY_CC_RESET, token->line, token->length, token->lexeme);
return; return;
+2 -2
View File
@@ -21,9 +21,9 @@ typedef struct {
} Toy_Token; } Toy_Token;
TOY_API void Toy_initLexer(Toy_Lexer* lexer, const char* source); TOY_API void Toy_initLexer(Toy_Lexer* lexer, const char* source);
TOY_API Toy_Token Toy_scanLexer(Toy_Lexer* lexer); TOY_API Toy_Token Toy_private_scanLexer(Toy_Lexer* lexer);
//for debugging //for debugging
TOY_API void Toy_printToken(Toy_Token* token); TOY_API void Toy_private_printToken(Toy_Token* token);
TOY_API void Toy_private_setComments(Toy_Lexer* lexer, bool enabled); TOY_API void Toy_private_setComments(Toy_Lexer* lexer, bool enabled);
+8 -6
View File
@@ -8,6 +8,7 @@
#include "toy_console_colors.h" #include "toy_console_colors.h"
#include <stdio.h> #include <stdio.h>
#include <string.h>
//hash util functions //hash util functions
static unsigned int hashString(const char* string, int length) { static unsigned int hashString(const char* string, int length) {
@@ -84,11 +85,11 @@ bool Toy_private_isTruthy(Toy_Literal x) {
} }
Toy_Literal Toy_private_toStringLiteral(Toy_RefString* ptr) { Toy_Literal Toy_private_toStringLiteral(Toy_RefString* ptr) {
return ((Toy_Literal){{ .string.ptr = ptr },TOY_LITERAL_STRING, 0}); return ((Toy_Literal){{ .string = { .ptr = ptr }},TOY_LITERAL_STRING, 0});
} }
Toy_Literal Toy_private_toIdentifierLiteral(Toy_RefString* ptr) { Toy_Literal Toy_private_toIdentifierLiteral(Toy_RefString* ptr) {
return ((Toy_Literal){{ .identifier.ptr = ptr, .identifier.hash = hashString(Toy_toCString(ptr), Toy_lengthRefString(ptr)) },TOY_LITERAL_IDENTIFIER, 0}); return ((Toy_Literal){{ .identifier = { .ptr = ptr, .hash = hashString(Toy_toCString(ptr), Toy_lengthRefString(ptr)) }},TOY_LITERAL_IDENTIFIER, 0});
} }
Toy_Literal* Toy_private_typePushSubtype(Toy_Literal* lit, Toy_Literal subtype) { Toy_Literal* Toy_private_typePushSubtype(Toy_Literal* lit, Toy_Literal subtype) {
@@ -155,6 +156,7 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) {
} }
case TOY_LITERAL_IDENTIFIER: { case TOY_LITERAL_IDENTIFIER: {
//NOTE: could optimise this by copying the hash manually, but it's a very small increase in performance
return TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_IDENTIFIER(original))); return TOY_TO_IDENTIFIER_LITERAL(Toy_copyRefString(TOY_AS_IDENTIFIER(original)));
} }
@@ -404,20 +406,20 @@ int Toy_hashLiteral(Toy_Literal lit) {
case TOY_LITERAL_FUNCTION: case TOY_LITERAL_FUNCTION:
case TOY_LITERAL_FUNCTION_NATIVE: case TOY_LITERAL_FUNCTION_NATIVE:
case TOY_LITERAL_FUNCTION_HOOK: case TOY_LITERAL_FUNCTION_HOOK:
return 0; //can't hash these return -1; //can't hash these
case TOY_LITERAL_IDENTIFIER: case TOY_LITERAL_IDENTIFIER:
return TOY_HASH_I(lit); //pre-computed return TOY_HASH_I(lit); //pre-computed
case TOY_LITERAL_TYPE: case TOY_LITERAL_TYPE:
return TOY_AS_TYPE(lit).typeOf; //nothing else I can do return -1; //not much i can really do
case TOY_LITERAL_OPAQUE: case TOY_LITERAL_OPAQUE:
case TOY_LITERAL_ANY: case TOY_LITERAL_ANY:
return -1; return -1;
default: default:
//should never bee seen //should never be seen
fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized literal type in hash: %d\n" TOY_CC_RESET, lit.type); fprintf(stderr, TOY_CC_ERROR "[internal] Unrecognized literal type in hash: %d\n" TOY_CC_RESET, lit.type);
return 0; return 0;
} }
@@ -453,7 +455,7 @@ void Toy_printLiteral(Toy_Literal literal) {
Toy_printLiteralCustom(literal, stdoutWrapper); Toy_printLiteralCustom(literal, stdoutWrapper);
} }
void Toy_printLiteralCustom(Toy_Literal literal, void (printFn)(const char*)) { void Toy_printLiteralCustom(Toy_Literal literal, Toy_PrintFn printFn) {
switch(literal.type) { switch(literal.type) {
case TOY_LITERAL_NULL: case TOY_LITERAL_NULL:
printFn("null"); printFn("null");
+8 -8
View File
@@ -10,8 +10,7 @@ struct Toy_Interpreter;
struct Toy_LiteralArray; struct Toy_LiteralArray;
typedef int (*Toy_NativeFn)(struct Toy_Interpreter* interpreter, struct Toy_LiteralArray* arguments); typedef int (*Toy_NativeFn)(struct Toy_Interpreter* interpreter, struct Toy_LiteralArray* arguments);
typedef int (*Toy_HookFn)(struct Toy_Interpreter* interpreter, struct Toy_Literal identifier, struct Toy_Literal alias); typedef int (*Toy_HookFn)(struct Toy_Interpreter* interpreter, struct Toy_Literal identifier, struct Toy_Literal alias);
typedef void (*Toy_PrintFn)(const char*);
#include <string.h>
typedef enum { typedef enum {
TOY_LITERAL_NULL, TOY_LITERAL_NULL,
@@ -118,12 +117,12 @@ typedef struct Toy_Literal {
#define TOY_TO_STRING_LITERAL(value) Toy_private_toStringLiteral(value) #define TOY_TO_STRING_LITERAL(value) Toy_private_toStringLiteral(value)
#define TOY_TO_ARRAY_LITERAL(value) ((Toy_Literal){{ .array = value }, TOY_LITERAL_ARRAY, 0}) #define TOY_TO_ARRAY_LITERAL(value) ((Toy_Literal){{ .array = value }, TOY_LITERAL_ARRAY, 0})
#define TOY_TO_DICTIONARY_LITERAL(value) ((Toy_Literal){{ .dictionary = value }, TOY_LITERAL_DICTIONARY, 0}) #define TOY_TO_DICTIONARY_LITERAL(value) ((Toy_Literal){{ .dictionary = value }, TOY_LITERAL_DICTIONARY, 0})
#define TOY_TO_FUNCTION_LITERAL(value, l) ((Toy_Literal){{ .function.inner.bytecode = value, .function.scope = NULL }, TOY_LITERAL_FUNCTION, l}) #define TOY_TO_FUNCTION_LITERAL(value, l) ((Toy_Literal){{ .function = { .inner = { .bytecode = value }, .scope = NULL }}, TOY_LITERAL_FUNCTION, l})
#define TOY_TO_FUNCTION_NATIVE_LITERAL(value) ((Toy_Literal){{ .function.inner.native = value, .function.scope = NULL }, TOY_LITERAL_FUNCTION_NATIVE, 0}) #define TOY_TO_FUNCTION_NATIVE_LITERAL(value) ((Toy_Literal){{ .function = { .inner = { .native = value }, .scope = NULL }}, TOY_LITERAL_FUNCTION_NATIVE, 0})
#define TOY_TO_FUNCTION_HOOK_LITERAL(value) ((Toy_Literal){{ .function.inner.hook = value, .function.scope = NULL }, TOY_LITERAL_FUNCTION_HOOK, 0}) #define TOY_TO_FUNCTION_HOOK_LITERAL(value) ((Toy_Literal){{ .function = { .inner = { .hook = value }, .scope = NULL }}, TOY_LITERAL_FUNCTION_HOOK, 0})
#define TOY_TO_IDENTIFIER_LITERAL(value) Toy_private_toIdentifierLiteral(value) #define TOY_TO_IDENTIFIER_LITERAL(value) Toy_private_toIdentifierLiteral(value)
#define TOY_TO_TYPE_LITERAL(value, c) ((Toy_Literal){{ .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }, TOY_LITERAL_TYPE, 0}) #define TOY_TO_TYPE_LITERAL(value, c) ((Toy_Literal){{ .type = { .typeOf = value, .constant = c, .subtypes = NULL, .capacity = 0, .count = 0 }}, TOY_LITERAL_TYPE, 0})
#define TOY_TO_OPAQUE_LITERAL(value, t) ((Toy_Literal){{ .opaque.ptr = value, .opaque.tag = t }, TOY_LITERAL_OPAQUE, 0}) #define TOY_TO_OPAQUE_LITERAL(value, t) ((Toy_Literal){{ .opaque = { .ptr = value, .tag = t }}, TOY_LITERAL_OPAQUE, 0})
//BUGFIX: For blank indexing //BUGFIX: For blank indexing
#define TOY_IS_INDEX_BLANK(value) ((value).type == TOY_LITERAL_INDEX_BLANK) #define TOY_IS_INDEX_BLANK(value) ((value).type == TOY_LITERAL_INDEX_BLANK)
@@ -151,5 +150,6 @@ TOY_API Toy_Literal Toy_copyLiteral(Toy_Literal original);
TOY_API bool Toy_literalsAreEqual(Toy_Literal lhs, Toy_Literal rhs); TOY_API bool Toy_literalsAreEqual(Toy_Literal lhs, Toy_Literal rhs);
TOY_API int Toy_hashLiteral(Toy_Literal lit); TOY_API int Toy_hashLiteral(Toy_Literal lit);
//not thread-safe
TOY_API void Toy_printLiteral(Toy_Literal literal); TOY_API void Toy_printLiteral(Toy_Literal literal);
TOY_API void Toy_printLiteralCustom(Toy_Literal literal, void (printFn)(const char*)); TOY_API void Toy_printLiteralCustom(Toy_Literal literal, Toy_PrintFn);
+2
View File
@@ -18,3 +18,5 @@ TOY_API bool Toy_setLiteralArray(Toy_LiteralArray* array, Toy_Literal index, Toy
TOY_API Toy_Literal Toy_getLiteralArray(Toy_LiteralArray* array, Toy_Literal index); TOY_API Toy_Literal Toy_getLiteralArray(Toy_LiteralArray* array, Toy_Literal index);
int Toy_findLiteralIndex(Toy_LiteralArray* array, Toy_Literal literal); int Toy_findLiteralIndex(Toy_LiteralArray* array, Toy_Literal literal);
//TODO: add a function to get the capacity & count
+18 -18
View File
@@ -7,7 +7,7 @@
#include <stdio.h> #include <stdio.h>
//util functions //util functions
static void setEntryValues(Toy_private_entry* entry, Toy_Literal key, Toy_Literal value) { static void setEntryValues(Toy_private_dictionary_entry* entry, Toy_Literal key, Toy_Literal value) {
//much simpler now //much simpler now
Toy_freeLiteral(entry->key); Toy_freeLiteral(entry->key);
entry->key = Toy_copyLiteral(key); entry->key = Toy_copyLiteral(key);
@@ -16,7 +16,7 @@ static void setEntryValues(Toy_private_entry* entry, Toy_Literal key, Toy_Litera
entry->value = Toy_copyLiteral(value); entry->value = Toy_copyLiteral(value);
} }
static Toy_private_entry* getEntryArray(Toy_private_entry* array, int capacity, Toy_Literal key, unsigned int hash, bool mustExist) { static Toy_private_dictionary_entry* getEntryArray(Toy_private_dictionary_entry* array, int capacity, Toy_Literal key, unsigned int hash, bool mustExist) {
//find "key", starting at index //find "key", starting at index
unsigned int index = hash % capacity; unsigned int index = hash % capacity;
unsigned int start = index; unsigned int start = index;
@@ -26,7 +26,7 @@ static Toy_private_entry* getEntryArray(Toy_private_entry* array, int capacity,
//literal probing and collision checking //literal probing and collision checking
while (index != start) { //WARNING: this is the only function allowed to retrieve an entry from the array while (index != start) { //WARNING: this is the only function allowed to retrieve an entry from the array
Toy_private_entry* entry = &array[index]; Toy_private_dictionary_entry* entry = &array[index];
if (TOY_IS_NULL(entry->key)) { //if key is empty, it's either empty or tombstone if (TOY_IS_NULL(entry->key)) { //if key is empty, it's either empty or tombstone
if (TOY_IS_NULL(entry->value) && !mustExist) { if (TOY_IS_NULL(entry->value) && !mustExist) {
@@ -46,9 +46,9 @@ static Toy_private_entry* getEntryArray(Toy_private_entry* array, int capacity,
return NULL; return NULL;
} }
static void adjustEntryCapacity(Toy_private_entry** dictionaryHandle, int oldCapacity, int capacity) { static void adjustEntryCapacity(Toy_private_dictionary_entry** dictionaryHandle, int oldCapacity, int capacity) {
//new entry space //new entry space
Toy_private_entry* newEntries = TOY_ALLOCATE(Toy_private_entry, capacity); Toy_private_dictionary_entry* newEntries = TOY_ALLOCATE(Toy_private_dictionary_entry, capacity);
for (int i = 0; i < capacity; i++) { for (int i = 0; i < capacity; i++) {
newEntries[i].key = TOY_TO_NULL_LITERAL; newEntries[i].key = TOY_TO_NULL_LITERAL;
@@ -62,19 +62,19 @@ static void adjustEntryCapacity(Toy_private_entry** dictionaryHandle, int oldCap
} }
//place the key and value in the new array (reusing string memory) //place the key and value in the new array (reusing string memory)
Toy_private_entry* entry = getEntryArray(newEntries, capacity, TOY_TO_NULL_LITERAL, Toy_hashLiteral((*dictionaryHandle)[i].key), false); Toy_private_dictionary_entry* entry = getEntryArray(newEntries, capacity, TOY_TO_NULL_LITERAL, Toy_hashLiteral((*dictionaryHandle)[i].key), false);
entry->key = (*dictionaryHandle)[i].key; entry->key = (*dictionaryHandle)[i].key;
entry->value = (*dictionaryHandle)[i].value; entry->value = (*dictionaryHandle)[i].value;
} }
//clear the old array //clear the old array
TOY_FREE_ARRAY(Toy_private_entry, *dictionaryHandle, oldCapacity); TOY_FREE_ARRAY(Toy_private_dictionary_entry, *dictionaryHandle, oldCapacity);
*dictionaryHandle = newEntries; *dictionaryHandle = newEntries;
} }
static bool setEntryArray(Toy_private_entry** dictionaryHandle, int* capacityPtr, int contains, Toy_Literal key, Toy_Literal value, int hash) { static bool setEntryArray(Toy_private_dictionary_entry** dictionaryHandle, int* capacityPtr, int contains, Toy_Literal key, Toy_Literal value, int hash) {
//expand array if needed //expand array if needed
if (contains + 1 > *capacityPtr * TOY_DICTIONARY_MAX_LOAD) { if (contains + 1 > *capacityPtr * TOY_DICTIONARY_MAX_LOAD) {
int oldCapacity = *capacityPtr; int oldCapacity = *capacityPtr;
@@ -82,7 +82,7 @@ static bool setEntryArray(Toy_private_entry** dictionaryHandle, int* capacityPtr
adjustEntryCapacity(dictionaryHandle, oldCapacity, *capacityPtr); //custom rather than automatic reallocation adjustEntryCapacity(dictionaryHandle, oldCapacity, *capacityPtr); //custom rather than automatic reallocation
} }
Toy_private_entry* entry = getEntryArray(*dictionaryHandle, *capacityPtr, key, hash, false); Toy_private_dictionary_entry* entry = getEntryArray(*dictionaryHandle, *capacityPtr, key, hash, false);
//true = contains increase //true = contains increase
if (TOY_IS_NULL(entry->key)) { if (TOY_IS_NULL(entry->key)) {
@@ -97,14 +97,14 @@ static bool setEntryArray(Toy_private_entry** dictionaryHandle, int* capacityPtr
return false; return false;
} }
static void freeEntry(Toy_private_entry* entry) { static void freeEntry(Toy_private_dictionary_entry* entry) {
Toy_freeLiteral(entry->key); Toy_freeLiteral(entry->key);
Toy_freeLiteral(entry->value); Toy_freeLiteral(entry->value);
entry->key = TOY_TO_NULL_LITERAL; entry->key = TOY_TO_NULL_LITERAL;
entry->value = TOY_TO_NULL_LITERAL; entry->value = TOY_TO_NULL_LITERAL;
} }
static void freeEntryArray(Toy_private_entry* array, int capacity) { static void freeEntryArray(Toy_private_dictionary_entry* array, int capacity) {
if (array == NULL) { if (array == NULL) {
return; return;
} }
@@ -115,7 +115,7 @@ static void freeEntryArray(Toy_private_entry* array, int capacity) {
} }
} }
TOY_FREE_ARRAY(Toy_private_entry, array, capacity); TOY_FREE_ARRAY(Toy_private_dictionary_entry, array, capacity);
} }
//exposed functions //exposed functions
@@ -141,7 +141,7 @@ void Toy_setLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key
} }
//BUGFIX: Can't hash a function //BUGFIX: Can't hash a function
if (TOY_IS_FUNCTION(key) || TOY_IS_FUNCTION_NATIVE(key)) { if (TOY_IS_FUNCTION(key) || TOY_IS_FUNCTION_NATIVE(key) || TOY_IS_FUNCTION_HOOK(key)) {
fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have function keys (set)\n" TOY_CC_RESET); fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have function keys (set)\n" TOY_CC_RESET);
return; return;
} }
@@ -166,7 +166,7 @@ Toy_Literal Toy_getLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Lite
} }
//BUGFIX: Can't hash a function //BUGFIX: Can't hash a function
if (TOY_IS_FUNCTION(key) || TOY_IS_FUNCTION_NATIVE(key)) { if (TOY_IS_FUNCTION(key) || TOY_IS_FUNCTION_NATIVE(key) || TOY_IS_FUNCTION_HOOK(key)) {
fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have function keys (get)\n" TOY_CC_RESET); fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have function keys (get)\n" TOY_CC_RESET);
return TOY_TO_NULL_LITERAL; return TOY_TO_NULL_LITERAL;
} }
@@ -176,7 +176,7 @@ Toy_Literal Toy_getLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Lite
return TOY_TO_NULL_LITERAL; return TOY_TO_NULL_LITERAL;
} }
Toy_private_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), true); Toy_private_dictionary_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), true);
if (entry != NULL) { if (entry != NULL) {
return Toy_copyLiteral(entry->value); return Toy_copyLiteral(entry->value);
@@ -193,7 +193,7 @@ void Toy_removeLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal
} }
//BUGFIX: Can't hash a function //BUGFIX: Can't hash a function
if (TOY_IS_FUNCTION(key) || TOY_IS_FUNCTION_NATIVE(key)) { if (TOY_IS_FUNCTION(key) || TOY_IS_FUNCTION_NATIVE(key) || TOY_IS_FUNCTION_HOOK(key)) {
fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have function keys (remove)\n" TOY_CC_RESET); fprintf(stderr, TOY_CC_ERROR "Dictionaries can't have function keys (remove)\n" TOY_CC_RESET);
return; return;
} }
@@ -203,7 +203,7 @@ void Toy_removeLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal
return; return;
} }
Toy_private_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), true); Toy_private_dictionary_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), true);
if (entry != NULL) { if (entry != NULL) {
freeEntry(entry); freeEntry(entry);
@@ -214,6 +214,6 @@ void Toy_removeLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal
bool Toy_existsLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key) { bool Toy_existsLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key) {
//null & not tombstoned //null & not tombstoned
Toy_private_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), false); Toy_private_dictionary_entry* entry = getEntryArray(dictionary->entries, dictionary->capacity, key, Toy_hashLiteral(key), false);
return !(TOY_IS_NULL(entry->key) && TOY_IS_NULL(entry->value)); return !(TOY_IS_NULL(entry->key) && TOY_IS_NULL(entry->value));
} }
+3 -3
View File
@@ -7,13 +7,13 @@
//TODO: benchmark this //TODO: benchmark this
#define TOY_DICTIONARY_MAX_LOAD 0.75 #define TOY_DICTIONARY_MAX_LOAD 0.75
typedef struct Toy_private_entry { typedef struct Toy_private_dictionary_entry {
Toy_Literal key; Toy_Literal key;
Toy_Literal value; Toy_Literal value;
} Toy_private_entry; } Toy_private_dictionary_entry;
typedef struct Toy_LiteralDictionary { typedef struct Toy_LiteralDictionary {
Toy_private_entry* entries; Toy_private_dictionary_entry* entries;
int capacity; int capacity;
int count; int count;
int contains; //count + tombstones, for internal use int contains; //count + tombstones, for internal use
+2 -3
View File
@@ -15,15 +15,14 @@ void* Toy_private_defaultMemoryAllocator(void* pointer, size_t oldSize, size_t n
if (newSize == 0) { if (newSize == 0) {
free(pointer); free(pointer);
return NULL; return NULL;
} }
void* mem = realloc(pointer, newSize); void* mem = realloc(pointer, newSize);
if (mem == NULL) { if (mem == NULL) {
fprintf(stderr, TOY_CC_ERROR "[internal] Memory allocation error (requested %d, replacing %d)\n" TOY_CC_RESET, (int)newSize, (int)oldSize); fprintf(stderr, TOY_CC_ERROR "[internal] Memory allocation error (requested %zu, replacing %zu)\n" TOY_CC_RESET, newSize, oldSize);
exit(-1); return NULL;
} }
return mem; return mem;
+6 -3
View File
@@ -2,13 +2,16 @@
#include "toy_common.h" #include "toy_common.h"
#define TOY_ALLOCATE(type, count) ((type*)Toy_reallocate(NULL, 0, sizeof(type) * (count)))
#define TOY_FREE(type, pointer) Toy_reallocate(pointer, sizeof(type), 0)
#define TOY_GROW_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity) * 2) #define TOY_GROW_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity) * 2)
#define TOY_GROW_CAPACITY_FAST(capacity) ((capacity) < 32 ? 32 : (capacity) * 2) #define TOY_GROW_CAPACITY_FAST(capacity) ((capacity) < 32 ? 32 : (capacity) * 2)
#define TOY_ALLOCATE(type, count) ((type*)Toy_reallocate(NULL, 0, sizeof(type) * (count)))
#define TOY_FREE(type, pointer) Toy_reallocate(pointer, sizeof(type), 0)
#define TOY_FREE_ARRAY(type, pointer, oldCount) Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), 0)
#define TOY_GROW_ARRAY(type, pointer, oldCount, count) (type*)Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) #define TOY_GROW_ARRAY(type, pointer, oldCount, count) (type*)Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count))
#define TOY_SHRINK_ARRAY(type, pointer, oldCount, count) (type*)Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) #define TOY_SHRINK_ARRAY(type, pointer, oldCount, count) (type*)Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count))
#define TOY_FREE_ARRAY(type, pointer, oldCount) Toy_reallocate((type*)pointer, sizeof(type) * (oldCount), 0)
//implementation details //implementation details
TOY_API void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize); TOY_API void* Toy_reallocate(void* pointer, size_t oldSize, size_t newSize);
+26 -2
View File
@@ -32,7 +32,7 @@ static void error(Toy_Parser* parser, Toy_Token token, const char* message) {
static void advance(Toy_Parser* parser) { static void advance(Toy_Parser* parser) {
parser->previous = parser->current; parser->previous = parser->current;
parser->current = Toy_scanLexer(parser->lexer); parser->current = Toy_private_scanLexer(parser->lexer);
if (parser->current.type == TOY_TOKEN_ERROR) { if (parser->current.type == TOY_TOKEN_ERROR) {
error(parser, parser->current, "Toy_Lexer error"); error(parser, parser->current, "Toy_Lexer error");
@@ -810,13 +810,20 @@ static Toy_Opcode indexAccess(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //
//eat the first //eat the first
if (!match(parser, TOY_TOKEN_COLON)) { if (!match(parser, TOY_TOKEN_COLON)) {
Toy_freeASTNode(first); Toy_freeASTNode(first);
first = NULL;
parsePrecedence(parser, &first, PREC_TERNARY); parsePrecedence(parser, &first, PREC_TERNARY);
match(parser, TOY_TOKEN_COLON); match(parser, TOY_TOKEN_COLON);
readFirst = true; readFirst = true;
} }
if (match(parser, TOY_TOKEN_BRACKET_RIGHT)) { if (!first) {
Toy_freeASTNode(first);
Toy_freeASTNode(second);
Toy_freeASTNode(third);
return TOY_OP_EOF;
}
if (match(parser, TOY_TOKEN_BRACKET_RIGHT)) {
if (readFirst) { if (readFirst) {
Toy_freeASTNode(second); Toy_freeASTNode(second);
second = NULL; second = NULL;
@@ -832,10 +839,18 @@ static Toy_Opcode indexAccess(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //
//eat the second //eat the second
if (!match(parser, TOY_TOKEN_COLON)) { if (!match(parser, TOY_TOKEN_COLON)) {
Toy_freeASTNode(second); Toy_freeASTNode(second);
second = NULL;
parsePrecedence(parser, &second, PREC_TERNARY); parsePrecedence(parser, &second, PREC_TERNARY);
match(parser, TOY_TOKEN_COLON); match(parser, TOY_TOKEN_COLON);
} }
if (!second) {
Toy_freeASTNode(first);
Toy_freeASTNode(second);
Toy_freeASTNode(third);
return TOY_OP_EOF;
}
if (match(parser, TOY_TOKEN_BRACKET_RIGHT)) { if (match(parser, TOY_TOKEN_BRACKET_RIGHT)) {
Toy_freeASTNode(third); Toy_freeASTNode(third);
third = NULL; third = NULL;
@@ -845,7 +860,16 @@ static Toy_Opcode indexAccess(Toy_Parser* parser, Toy_ASTNode** nodeHandle) { //
//eat the third //eat the third
Toy_freeASTNode(third); Toy_freeASTNode(third);
third = NULL;
parsePrecedence(parser, &third, PREC_TERNARY); parsePrecedence(parser, &third, PREC_TERNARY);
if (!third) {
Toy_freeASTNode(first);
Toy_freeASTNode(second);
Toy_freeASTNode(third);
return TOY_OP_EOF;
}
Toy_emitASTNodeIndex(nodeHandle, first, second, third); Toy_emitASTNodeIndex(nodeHandle, first, second, third);
consume(parser, TOY_TOKEN_BRACKET_RIGHT, "Expected ']' in index notation"); consume(parser, TOY_TOKEN_BRACKET_RIGHT, "Expected ']' in index notation");
-2
View File
@@ -1,7 +1,5 @@
#include "toy_refstring.h" #include "toy_refstring.h"
#include <string.h>
//memory allocation //memory allocation
extern void* Toy_private_defaultMemoryAllocator(void* pointer, size_t oldSize, size_t newSize); extern void* Toy_private_defaultMemoryAllocator(void* pointer, size_t oldSize, size_t newSize);
static Toy_RefStringAllocatorFn allocate = Toy_private_defaultMemoryAllocator; static Toy_RefStringAllocatorFn allocate = Toy_private_defaultMemoryAllocator;
+6 -4
View File
@@ -1,13 +1,12 @@
#pragma once #pragma once
#include <stdbool.h>
#include <stddef.h>
#include "toy_common.h" #include "toy_common.h"
#include <string.h>
//memory allocation hook //memory allocation hook
typedef void* (*Toy_RefStringAllocatorFn)(void* pointer, size_t oldSize, size_t newSize); typedef void* (*Toy_RefStringAllocatorFn)(void* pointer, size_t oldSize, size_t newSize);
void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn); TOY_API void Toy_setRefStringAllocatorFn(Toy_RefStringAllocatorFn);
//the RefString structure //the RefString structure
typedef struct Toy_RefString { typedef struct Toy_RefString {
@@ -27,3 +26,6 @@ TOY_API Toy_RefString* Toy_deepCopyRefString(Toy_RefString* refString);
TOY_API const char* Toy_toCString(Toy_RefString* refString); TOY_API const char* Toy_toCString(Toy_RefString* refString);
TOY_API bool Toy_equalsRefString(Toy_RefString* lhs, Toy_RefString* rhs); TOY_API bool Toy_equalsRefString(Toy_RefString* lhs, Toy_RefString* rhs);
TOY_API bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring); TOY_API bool Toy_equalsRefStringCString(Toy_RefString* lhs, char* cstring);
//TODO: merge refstring memory
+7 -3
View File
@@ -126,7 +126,7 @@ static bool checkType(Toy_Literal typeLiteral, Toy_Literal original, Toy_Literal
} }
//find the internal child of original that matches this child of value //find the internal child of original that matches this child of value
Toy_private_entry* ptr = NULL; Toy_private_dictionary_entry* ptr = NULL;
for (int j = 0; j < TOY_AS_DICTIONARY(original)->capacity; j++) { for (int j = 0; j < TOY_AS_DICTIONARY(original)->capacity; j++) {
if (Toy_literalsAreEqual(TOY_AS_DICTIONARY(original)->entries[j].key, TOY_AS_DICTIONARY(value)->entries[i].key)) { if (Toy_literalsAreEqual(TOY_AS_DICTIONARY(original)->entries[j].key, TOY_AS_DICTIONARY(value)->entries[i].key)) {
@@ -159,6 +159,10 @@ static bool checkType(Toy_Literal typeLiteral, Toy_Literal original, Toy_Literal
return false; return false;
} }
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_OPAQUE && !TOY_IS_OPAQUE(value)) {
return false;
}
return true; return true;
} }
@@ -185,7 +189,7 @@ Toy_Scope* Toy_popScope(Toy_Scope* scope) {
Toy_Scope* ret = scope->ancestor; Toy_Scope* ret = scope->ancestor;
//BUGFIX: when freeing a scope, free the function's scopes manually //BUGFIX: when freeing a scope, free the functions' scopes manually - I *think* this is related to the closure hack-in
for (int i = 0; i < scope->variables.capacity; i++) { for (int i = 0; i < scope->variables.capacity; i++) {
//handle keys, just in case //handle keys, just in case
if (TOY_IS_FUNCTION(scope->variables.entries[i].key)) { if (TOY_IS_FUNCTION(scope->variables.entries[i].key)) {
@@ -286,7 +290,7 @@ bool Toy_setScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal value,
} }
//actually assign //actually assign
Toy_setLiteralDictionary(&scope->variables, key, value); Toy_setLiteralDictionary(&scope->variables, key, value); //key & value are copied here
Toy_freeLiteral(typeLiteral); Toy_freeLiteral(typeLiteral);
Toy_freeLiteral(original); Toy_freeLiteral(original);
+1
View File
@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "toy_literal.h"
#include "toy_literal_array.h" #include "toy_literal_array.h"
#include "toy_literal_dictionary.h" #include "toy_literal_dictionary.h"
Binary file not shown.
@@ -0,0 +1 @@
"a"[--];
+11 -2
View File
@@ -1,12 +1,21 @@
//memoize the fib function
var memo: [int : int] = [:];
fn fib(n : int) { fn fib(n : int) {
if (n < 2) { if (n < 2) {
return n; return n;
} }
return fib(n-1) + fib(n-2); var result = memo[n];
if (result == null) {
result = fib(n-1) + fib(n-2);
memo[n] = result;
} }
for (var i = 0; i < 20; i++) { return result;
}
for (var i = 0; i < 40; i++) {
var res = fib(i); var res = fib(i);
print string i + ": " + string res; print string i + ": " + string res;
} }
+26 -26
View File
@@ -20,14 +20,14 @@ static void noPrintFn(const char* output) {
} }
void error(char* msg) { void error(char* msg) {
printf("%s", msg); printf("%s\n", msg);
exit(-1); exit(-1);
} }
int main() { int main() {
{ {
size_t size = 0; size_t size = 0;
const char* source = Toy_readFile("scripts/call-from-host.toy", &size); const char* source = (const char*)Toy_readFile("scripts/call-from-host.toy", &size);
const unsigned char* tb = Toy_compileString(source, &size); const unsigned char* tb = Toy_compileString(source, &size);
free((void*)source); free((void*)source);
@@ -41,7 +41,7 @@ int main() {
//test answer //test answer
{ {
interpreter.printOutput("Testing answer\n"); interpreter.printOutput("Testing answer");
Toy_LiteralArray arguments; Toy_LiteralArray arguments;
Toy_initLiteralArray(&arguments); Toy_initLiteralArray(&arguments);
@@ -52,15 +52,15 @@ int main() {
//check the results //check the results
if (arguments.count != 0) { if (arguments.count != 0) {
error("Arguments has the wrong number of members\n"); error("Arguments has the wrong number of members");
} }
if (returns.count != 1) { if (returns.count != 1) {
error("Returns has the wrong number of members\n"); error("Returns has the wrong number of members");
} }
if (!TOY_IS_INTEGER(returns.literals[0]) || TOY_AS_INTEGER(returns.literals[0]) != 42) { if (!TOY_IS_INTEGER(returns.literals[0]) || TOY_AS_INTEGER(returns.literals[0]) != 42) {
error("Returned value is incorrect\n"); error("Returned value is incorrect");
} }
Toy_freeLiteralArray(&arguments); Toy_freeLiteralArray(&arguments);
@@ -69,7 +69,7 @@ int main() {
//test identity //test identity
{ {
interpreter.printOutput("Testing identity\n"); interpreter.printOutput("Testing identity");
Toy_LiteralArray arguments; Toy_LiteralArray arguments;
Toy_initLiteralArray(&arguments); Toy_initLiteralArray(&arguments);
@@ -85,17 +85,17 @@ int main() {
//check the results //check the results
if (arguments.count != 0) { if (arguments.count != 0) {
error("Arguments has the wrong number of members\n"); error("Arguments has the wrong number of members");
} }
if (returns.count != 1) { if (returns.count != 1) {
error("Returns has the wrong number of members\n"); error("Returns has the wrong number of members");
} }
float epsilon = 0.1; //because floats are evil float epsilon = 0.1; //because floats are evil
if (!TOY_IS_FLOAT(returns.literals[0]) || fabs(TOY_AS_FLOAT(returns.literals[0]) - pi) > epsilon) { if (!TOY_IS_FLOAT(returns.literals[0]) || fabs(TOY_AS_FLOAT(returns.literals[0]) - pi) > epsilon) {
error("Returned value is incorrect\n"); error("Returned value is incorrect");
} }
Toy_freeLiteralArray(&arguments); Toy_freeLiteralArray(&arguments);
@@ -104,7 +104,7 @@ int main() {
//test makeCounter (closures) //test makeCounter (closures)
{ {
interpreter.printOutput("Testing makeCounter (closures)\n"); interpreter.printOutput("Testing makeCounter (closures)");
Toy_LiteralArray arguments; Toy_LiteralArray arguments;
Toy_initLiteralArray(&arguments); Toy_initLiteralArray(&arguments);
@@ -115,11 +115,11 @@ int main() {
//check the results //check the results
if (arguments.count != 0) { if (arguments.count != 0) {
error("Arguments has the wrong number of members\n"); error("Arguments has the wrong number of members");
} }
if (returns.count != 1) { if (returns.count != 1) {
error("Returns has the wrong number of members\n"); error("Returns has the wrong number of members");
} }
//grab the resulting literal //grab the resulting literal
@@ -139,15 +139,15 @@ int main() {
//check the results //check the results
if (arguments.count != 0) { if (arguments.count != 0) {
error("Arguments (1) has the wrong number of members\n"); error("Arguments (1) has the wrong number of members");
} }
if (returns.count != 1) { if (returns.count != 1) {
error("Returns (1) has the wrong number of members\n"); error("Returns (1) has the wrong number of members");
} }
if (!TOY_IS_INTEGER(returns.literals[0]) || TOY_AS_INTEGER(returns.literals[0]) != 1) { if (!TOY_IS_INTEGER(returns.literals[0]) || TOY_AS_INTEGER(returns.literals[0]) != 1) {
error("Returned value (1) is incorrect\n"); error("Returned value (1) is incorrect");
} }
Toy_freeLiteralArray(&arguments); Toy_freeLiteralArray(&arguments);
@@ -164,15 +164,15 @@ int main() {
//check the results //check the results
if (arguments.count != 0) { if (arguments.count != 0) {
error("Arguments (2) has the wrong number of members\n"); error("Arguments (2) has the wrong number of members");
} }
if (returns.count != 1) { if (returns.count != 1) {
error("Returns (2) has the wrong number of members\n"); error("Returns (2) has the wrong number of members");
} }
if (!TOY_IS_INTEGER(returns.literals[0]) || TOY_AS_INTEGER(returns.literals[0]) != 2) { if (!TOY_IS_INTEGER(returns.literals[0]) || TOY_AS_INTEGER(returns.literals[0]) != 2) {
error("Returned value (2) is incorrect\n"); error("Returned value (2) is incorrect");
} }
Toy_freeLiteralArray(&arguments); Toy_freeLiteralArray(&arguments);
@@ -189,15 +189,15 @@ int main() {
//check the results //check the results
if (arguments.count != 0) { if (arguments.count != 0) {
error("Arguments (3) has the wrong number of members\n"); error("Arguments (3) has the wrong number of members");
} }
if (returns.count != 1) { if (returns.count != 1) {
error("Returns (3) has the wrong number of members\n"); error("Returns (3) has the wrong number of members");
} }
if (!TOY_IS_INTEGER(returns.literals[0]) || TOY_AS_INTEGER(returns.literals[0]) != 3) { if (!TOY_IS_INTEGER(returns.literals[0]) || TOY_AS_INTEGER(returns.literals[0]) != 3) {
error("Returned value (3) is incorrect\n"); error("Returned value (3) is incorrect");
} }
Toy_freeLiteralArray(&arguments); Toy_freeLiteralArray(&arguments);
@@ -209,7 +209,7 @@ int main() {
//test assertion failure //test assertion failure
{ {
interpreter.printOutput("Testing assertion failure\n"); interpreter.printOutput("Testing assertion failure");
Toy_setInterpreterAssert(&interpreter, noPrintFn); Toy_setInterpreterAssert(&interpreter, noPrintFn);
@@ -222,15 +222,15 @@ int main() {
//check the results //check the results
if (arguments.count != 0) { if (arguments.count != 0) {
error("Arguments has the wrong number of members\n"); error("Arguments has the wrong number of members");
} }
if (returns.count != 1 || !TOY_IS_NULL(returns.literals[0])) { if (returns.count != 1 || !TOY_IS_NULL(returns.literals[0])) {
error("Returns has the wrong number of members\n"); error("Returns has the wrong number of members");
} }
if (!ret) { if (!ret) {
error("Assertion gives the wrong return value\n"); error("Assertion gives the wrong return value");
} }
Toy_freeLiteralArray(&arguments); Toy_freeLiteralArray(&arguments);
+3 -3
View File
@@ -39,7 +39,7 @@ int main() {
Toy_writeCompiler(&compiler, node); Toy_writeCompiler(&compiler, node);
//collate //collate
int size = 0; size_t size = 0;
unsigned char* bytecode = Toy_collateCompiler(&compiler, &size); unsigned char* bytecode = Toy_collateCompiler(&compiler, &size);
//cleanup //cleanup
@@ -52,7 +52,7 @@ int main() {
{ {
//source //source
size_t sourceLength = 0; size_t sourceLength = 0;
const char* source = Toy_readFile("scripts/compiler_sample_code.toy", &sourceLength); const char* source = (const char*)Toy_readFile("scripts/compiler_sample_code.toy", &sourceLength);
//test basic compilation & collation //test basic compilation & collation
Toy_Lexer lexer; Toy_Lexer lexer;
@@ -78,7 +78,7 @@ int main() {
} }
//collate //collate
int size = 0; size_t size = 0;
unsigned char* bytecode = Toy_collateCompiler(&compiler, &size); unsigned char* bytecode = Toy_collateCompiler(&compiler, &size);
//cleanup //cleanup
+2 -2
View File
@@ -53,7 +53,7 @@ void runSourceCustom(const char* source) {
void runSourceFileCustom(const char* fname) { void runSourceFileCustom(const char* fname) {
size_t size = 0; //not used size_t size = 0; //not used
const char* source = Toy_readFile(fname, &size); const char* source = (const char*)Toy_readFile(fname, &size);
runSourceCustom(source); runSourceCustom(source);
free((void*)source); free((void*)source);
} }
@@ -87,7 +87,7 @@ int main() {
Toy_writeCompiler(&compiler, node); Toy_writeCompiler(&compiler, node);
//collate //collate
int size = 0; size_t size = 0;
const unsigned char* bytecode = Toy_collateCompiler(&compiler, &size); const unsigned char* bytecode = Toy_collateCompiler(&compiler, &size);
//NOTE: suppress print output for testing //NOTE: suppress print output for testing
+4 -4
View File
@@ -15,10 +15,10 @@ int main() {
Toy_initLexer(&lexer, source); Toy_initLexer(&lexer, source);
//get each token //get each token
Toy_Token print = Toy_scanLexer(&lexer); Toy_Token print = Toy_private_scanLexer(&lexer);
Toy_Token null = Toy_scanLexer(&lexer); Toy_Token null = Toy_private_scanLexer(&lexer);
Toy_Token semi = Toy_scanLexer(&lexer); Toy_Token semi = Toy_private_scanLexer(&lexer);
Toy_Token eof = Toy_scanLexer(&lexer); Toy_Token eof = Toy_private_scanLexer(&lexer);
//test each token is correct //test each token is correct
if (strncmp(print.lexeme, "print", print.length)) { if (strncmp(print.lexeme, "print", print.length)) {
+2 -2
View File
@@ -105,7 +105,7 @@ int main() {
//compile the source //compile the source
size_t size = 0; size_t size = 0;
const char* source = Toy_readFile(fname, &size); const char* source = (const char*)Toy_readFile(fname, &size);
if (!source) { if (!source) {
printf(TOY_CC_ERROR "Failed to load file: %s\n" TOY_CC_RESET, fname); printf(TOY_CC_ERROR "Failed to load file: %s\n" TOY_CC_RESET, fname);
failedAsserts++; failedAsserts++;
@@ -140,7 +140,7 @@ int main() {
//compile the source //compile the source
size_t size = 0; size_t size = 0;
const char* source = Toy_readFile(fname, &size); const char* source = (const char*)Toy_readFile(fname, &size);
if (!source) { if (!source) {
printf(TOY_CC_ERROR "Failed to load file: %s\n" TOY_CC_RESET, fname); printf(TOY_CC_ERROR "Failed to load file: %s\n" TOY_CC_RESET, fname);
failedAsserts++; failedAsserts++;
+3 -2
View File
@@ -50,7 +50,7 @@ const unsigned char* compileStringCustom(const char* source, size_t* size) {
} }
//get the bytecode dump //get the bytecode dump
const unsigned char* tb = Toy_collateCompiler(&compiler, (int*)(size)); const unsigned char* tb = Toy_collateCompiler(&compiler, size);
//cleanup //cleanup
Toy_freeCompiler(&compiler); Toy_freeCompiler(&compiler);
@@ -84,7 +84,7 @@ void runSourceCustom(const char* source) {
void runSourceFileCustom(const char* fname) { void runSourceFileCustom(const char* fname) {
size_t size = 0; //not used size_t size = 0; //not used
const char* source = Toy_readFile(fname, &size); const char* source = (const char*)Toy_readFile(fname, &size);
runSourceCustom(source); runSourceCustom(source);
free((void*)source); free((void*)source);
} }
@@ -101,6 +101,7 @@ int main() {
"declare-types-array.toy", "declare-types-array.toy",
"declare-types-dictionary-key.toy", "declare-types-dictionary-key.toy",
"declare-types-dictionary-value.toy", "declare-types-dictionary-value.toy",
"index-access-bugfix.toy",
"index-arrays-non-integer.toy", "index-arrays-non-integer.toy",
"string-concat.toy", "string-concat.toy",
"unary-inverted-nothing.toy", "unary-inverted-nothing.toy",
+1 -1
View File
@@ -68,7 +68,7 @@ static int consume(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
int main() { int main() {
{ {
size_t size = 0; size_t size = 0;
const char* source = Toy_readFile("scripts/opaque-data-type.toy", &size); const char* source = (const char*)Toy_readFile("scripts/opaque-data-type.toy", &size);
const unsigned char* tb = Toy_compileString(source, &size); const unsigned char* tb = Toy_compileString(source, &size);
free((void*)source); free((void*)source);
+1 -1
View File
@@ -58,7 +58,7 @@ int main() {
{ {
//get the source file //get the source file
size_t size = 0; size_t size = 0;
const char* source = Toy_readFile("scripts/parser_sample_code.toy", &size); const char* source = (const char*)Toy_readFile("scripts/parser_sample_code.toy", &size);
//test parsing a chunk of junk (valgrind will find leaks) //test parsing a chunk of junk (valgrind will find leaks)
Toy_Lexer lexer; Toy_Lexer lexer;
+4 -1
View File
@@ -39,11 +39,14 @@ static void* trackerAllocator(void* pointer, size_t oldSize, size_t newSize) {
return mem; return mem;
} }
int main(int argc, char* argv[]) { int main(int argc, const char* argv[]) {
if (argc <= 1) { if (argc <= 1) {
return -1; return -1;
} }
//not used, except for print
Toy_initCommandLine(argc, argv);
//setup for runner //setup for runner
Toy_initDriveDictionary(); Toy_initDriveDictionary();