Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 733df87c08 | |||
| bfd506f497 | |||
| 18b59c9e84 | |||
| d3eb31d964 | |||
| 07f4a98b95 | |||
| 0949fd6ff9 | |||
| 03e5096f10 | |||
| bb81b8c474 | |||
| cf6db57787 |
+4
-2
@@ -115,13 +115,15 @@
|
|||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>$(SolutionDir)/source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(SolutionDir)/source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||||
<PreprocessorDefinitions>LIB_RUNNER_EXPORT</PreprocessorDefinitions>
|
<PreprocessorDefinitions>
|
||||||
|
</PreprocessorDefinitions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||||
<PreprocessorDefinitions>LIB_RUNNER_EXPORT</PreprocessorDefinitions>
|
<PreprocessorDefinitions>
|
||||||
|
</PreprocessorDefinitions>
|
||||||
<AdditionalIncludeDirectories>$(SolutionDir)/source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(SolutionDir)/source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
|
|||||||
@@ -132,6 +132,7 @@
|
|||||||
<ClCompile Include="source\toy_literal_dictionary.c" />
|
<ClCompile Include="source\toy_literal_dictionary.c" />
|
||||||
<ClCompile Include="source\toy_memory.c" />
|
<ClCompile Include="source\toy_memory.c" />
|
||||||
<ClCompile Include="source\toy_parser.c" />
|
<ClCompile Include="source\toy_parser.c" />
|
||||||
|
<ClCompile Include="source\toy_reffunction.c" />
|
||||||
<ClCompile Include="source\toy_refstring.c" />
|
<ClCompile Include="source\toy_refstring.c" />
|
||||||
<ClCompile Include="source\toy_scope.c" />
|
<ClCompile Include="source\toy_scope.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -152,6 +153,7 @@
|
|||||||
<ClInclude Include="source\toy_memory.h" />
|
<ClInclude Include="source\toy_memory.h" />
|
||||||
<ClInclude Include="source\toy_opcodes.h" />
|
<ClInclude Include="source\toy_opcodes.h" />
|
||||||
<ClInclude Include="source\toy_parser.h" />
|
<ClInclude Include="source\toy_parser.h" />
|
||||||
|
<ClInclude Include="source\toy_reffunction.h" />
|
||||||
<ClInclude Include="source\toy_refstring.h" />
|
<ClInclude Include="source\toy_refstring.h" />
|
||||||
<ClInclude Include="source\toy_scope.h" />
|
<ClInclude Include="source\toy_scope.h" />
|
||||||
<ClInclude Include="source\toy_token_types.h" />
|
<ClInclude Include="source\toy_token_types.h" />
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
# Optimisation Options
|
|
||||||
# export CFLAGS+=-O2 -mtune=native -march=native
|
|
||||||
# export CFLAGS+=-fsanitize=address,undefined
|
|
||||||
|
|
||||||
export CFLAGS+=-std=c18 -pedantic -Werror
|
export CFLAGS+=-std=c18 -pedantic -Werror
|
||||||
|
|
||||||
export TOY_OUTDIR = out
|
export TOY_OUTDIR = out
|
||||||
@@ -34,6 +30,10 @@ library-release: clean $(TOY_OUTDIR)
|
|||||||
static-release: clean $(TOY_OUTDIR)
|
static-release: clean $(TOY_OUTDIR)
|
||||||
$(MAKE) -j8 -C source static-release
|
$(MAKE) -j8 -C source static-release
|
||||||
|
|
||||||
|
#distribution
|
||||||
|
dist: export CFLAGS+=-O2 -mtune=native -march=native
|
||||||
|
dist: repl-release
|
||||||
|
|
||||||
#utils
|
#utils
|
||||||
test: clean $(TOY_OUTDIR)
|
test: clean $(TOY_OUTDIR)
|
||||||
$(MAKE) -C test
|
$(MAKE) -C test
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
var s = "42";
|
|
||||||
var t = "69";
|
|
||||||
|
|
||||||
print int (s + t) - 1;
|
|
||||||
+1
-1
@@ -4,7 +4,7 @@ fn fib(n : int) {
|
|||||||
return fib(n-1) + fib(n-2);
|
return fib(n-1) + fib(n-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < 20; i++) {
|
for (var i = 0; i <= 35; i++) {
|
||||||
var res = fib(i);
|
var res = fib(i);
|
||||||
print string i + ": " + string res;
|
print string i + ": " + string res;
|
||||||
}
|
}
|
||||||
+3
-1
@@ -61,8 +61,10 @@ to the same string to save memory, and you can just create a new one of these va
|
|||||||
rather than copying entirely for a speed boost. This module has it's own memory allocator system that is
|
rather than copying entirely for a speed boost. This module has it's own memory allocator system that is
|
||||||
plugged into the main memory allocator.
|
plugged into the main memory allocator.
|
||||||
|
|
||||||
|
`Toy_RefFunction` acts similarly to `Toy_RefString`, but instead operates on function bytecode.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "toy_scope.h"
|
#include "toy_scope.h"
|
||||||
#include "toy_refstring.h"
|
#include "toy_refstring.h"
|
||||||
|
#include "toy_reffunction.h"
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@ STATIC_ASSERT(sizeof(unsigned char) == 1);
|
|||||||
STATIC_ASSERT(sizeof(unsigned short) == 2);
|
STATIC_ASSERT(sizeof(unsigned short) == 2);
|
||||||
STATIC_ASSERT(sizeof(unsigned int) == 4);
|
STATIC_ASSERT(sizeof(unsigned int) == 4);
|
||||||
|
|
||||||
#ifndef TOY_EXPORT
|
#ifndef TOY_DISABLE_REPL
|
||||||
|
|
||||||
//declare the singleton with default values
|
//declare the singleton with default values
|
||||||
Toy_CommandLine Toy_commandLine = {
|
Toy_CommandLine Toy_commandLine = {
|
||||||
|
|||||||
+2
-2
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#define TOY_VERSION_MAJOR 1
|
#define TOY_VERSION_MAJOR 1
|
||||||
#define TOY_VERSION_MINOR 1
|
#define TOY_VERSION_MINOR 1
|
||||||
#define TOY_VERSION_PATCH 2
|
#define TOY_VERSION_PATCH 4
|
||||||
#define TOY_VERSION_BUILD __DATE__ " " __TIME__
|
#define TOY_VERSION_BUILD __DATE__ " " __TIME__
|
||||||
|
|
||||||
//platform/compiler-specific instructions
|
//platform/compiler-specific instructions
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TOY_EXPORT
|
#ifndef TOY_DISABLE_REPL
|
||||||
|
|
||||||
//for processing the command line arguments in the repl
|
//for processing the command line arguments in the repl
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -518,8 +518,7 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
//create the function in the literal cache (by storing the compiler object)
|
//create the function in the literal cache (by storing the compiler object)
|
||||||
Toy_Literal fnLiteral = TOY_TO_FUNCTION_LITERAL(fnCompiler, 0);
|
Toy_Literal fnLiteral = ((Toy_Literal){ .as = { .generic = fnCompiler }, .type = TOY_LITERAL_FUNCTION_INTERMEDIATE});
|
||||||
fnLiteral.type = TOY_LITERAL_FUNCTION_INTERMEDIATE; //NOTE: changing type
|
|
||||||
|
|
||||||
//push the name
|
//push the name
|
||||||
int identifierIndex = Toy_findLiteralIndex(&compiler->literalCache, node->fnDecl.identifier);
|
int identifierIndex = Toy_findLiteralIndex(&compiler->literalCache, node->fnDecl.identifier);
|
||||||
@@ -1210,7 +1209,7 @@ static unsigned char* collateCompilerHeaderOpt(Toy_Compiler* compiler, size_t* s
|
|||||||
case TOY_LITERAL_FUNCTION_INTERMEDIATE: {
|
case TOY_LITERAL_FUNCTION_INTERMEDIATE: {
|
||||||
//extract the compiler
|
//extract the compiler
|
||||||
Toy_Literal fn = compiler->literalCache.literals[i];
|
Toy_Literal fn = compiler->literalCache.literals[i];
|
||||||
void* fnCompiler = TOY_AS_FUNCTION(fn).inner.bytecode; //store the compiler here for now
|
void* fnCompiler = fn.as.generic; //store the compiler here for now
|
||||||
|
|
||||||
//collate the function into bytecode (without header)
|
//collate the function into bytecode (without header)
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
//NOTE: you need both font AND background for these to work
|
/* toy_console_colors.h - console utility
|
||||||
|
|
||||||
|
This file provides a number of macros that can set the color of text in a console
|
||||||
|
window. These are used for convenience only. They are supposed to be dropped into
|
||||||
|
a printf()'s first argument, like so:
|
||||||
|
|
||||||
|
printf(TOY_CC_NOTICE "Hello world" TOY_CC_RESET);
|
||||||
|
|
||||||
|
NOTE: you need both font AND background for these to work
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
//platform/compiler-specific instructions
|
//platform/compiler-specific instructions
|
||||||
#if defined(__linux__) || defined(__MINGW32__) || defined(__GNUC__)
|
#if defined(__linux__) || defined(__MINGW32__) || defined(__GNUC__)
|
||||||
|
|||||||
@@ -1193,7 +1193,7 @@ static void readInterpreterSections(Toy_Interpreter* interpreter);
|
|||||||
//also supports identifier & arg1 to be other way around (looseFirstArgument)
|
//also supports identifier & arg1 to be other way around (looseFirstArgument)
|
||||||
static bool execFnCall(Toy_Interpreter* interpreter, bool looseFirstArgument) {
|
static bool execFnCall(Toy_Interpreter* interpreter, bool looseFirstArgument) {
|
||||||
//BUGFIX: depth check - don't drown!
|
//BUGFIX: depth check - don't drown!
|
||||||
if (interpreter->depth >= 200) {
|
if (interpreter->depth >= 1000) {
|
||||||
interpreter->errorOutput("Infinite recursion detected - panicking\n");
|
interpreter->errorOutput("Infinite recursion detected - panicking\n");
|
||||||
interpreter->panic = true;
|
interpreter->panic = true;
|
||||||
return false;
|
return false;
|
||||||
@@ -1323,8 +1323,8 @@ bool Toy_callLiteralFn(Toy_Interpreter* interpreter, Toy_Literal func, Toy_Liter
|
|||||||
//init the inner interpreter manually
|
//init the inner interpreter manually
|
||||||
Toy_initLiteralArray(&inner.literalCache);
|
Toy_initLiteralArray(&inner.literalCache);
|
||||||
inner.scope = Toy_pushScope(func.as.function.scope);
|
inner.scope = Toy_pushScope(func.as.function.scope);
|
||||||
inner.bytecode = TOY_AS_FUNCTION(func).inner.bytecode;
|
inner.bytecode = ((Toy_RefFunction*)(TOY_AS_FUNCTION(func).inner.ptr))->data;
|
||||||
inner.length = TOY_AS_FUNCTION_BYTECODE_LENGTH(func);
|
inner.length = ((Toy_RefFunction*)(TOY_AS_FUNCTION(func).inner.ptr))->length;
|
||||||
inner.count = 0;
|
inner.count = 0;
|
||||||
inner.codeStart = -1;
|
inner.codeStart = -1;
|
||||||
inner.depth = interpreter->depth + 1;
|
inner.depth = interpreter->depth + 1;
|
||||||
@@ -2428,20 +2428,16 @@ static void readInterpreterSections(Toy_Interpreter* interpreter) {
|
|||||||
//get the size of the function
|
//get the size of the function
|
||||||
size_t size = (size_t)readShort(interpreter->bytecode, &interpreter->count);
|
size_t size = (size_t)readShort(interpreter->bytecode, &interpreter->count);
|
||||||
|
|
||||||
//read the function code (literal cache and all)
|
|
||||||
unsigned char* bytes = TOY_ALLOCATE(unsigned char, size);
|
|
||||||
memcpy(bytes, interpreter->bytecode + interpreter->count, size); //TODO: -1 for the ending mark
|
|
||||||
interpreter->count += size;
|
|
||||||
|
|
||||||
//assert that the last memory slot is function end
|
//assert that the last memory slot is function end
|
||||||
if (bytes[size - 1] != TOY_OP_FN_END) {
|
if (interpreter->bytecode[interpreter->count + size - 1] != TOY_OP_FN_END) {
|
||||||
interpreter->errorOutput("[internal] Failed to find function end");
|
interpreter->errorOutput("[internal] Failed to find function end");
|
||||||
TOY_FREE_ARRAY(unsigned char, bytes, size);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//change the type to normal
|
//copies internally, since functions can exist independant of literalCache
|
||||||
interpreter->literalCache.literals[i] = TOY_TO_FUNCTION_LITERAL(bytes, size);
|
interpreter->literalCache.literals[i] = TOY_TO_FUNCTION_LITERAL(Toy_createRefFunction(interpreter->bytecode + interpreter->count, size));
|
||||||
|
|
||||||
|
interpreter->count += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-12
@@ -59,7 +59,7 @@ void Toy_freeLiteral(Toy_Literal literal) {
|
|||||||
if (TOY_IS_FUNCTION(literal)) {
|
if (TOY_IS_FUNCTION(literal)) {
|
||||||
Toy_popScope(TOY_AS_FUNCTION(literal).scope);
|
Toy_popScope(TOY_AS_FUNCTION(literal).scope);
|
||||||
TOY_AS_FUNCTION(literal).scope = NULL;
|
TOY_AS_FUNCTION(literal).scope = NULL;
|
||||||
TOY_FREE_ARRAY(unsigned char, TOY_AS_FUNCTION(literal).inner.bytecode, TOY_AS_FUNCTION_BYTECODE_LENGTH(literal));
|
Toy_deleteRefFunction((Toy_RefFunction*)(TOY_AS_FUNCTION(literal).inner.ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TOY_IS_TYPE(literal) && TOY_AS_TYPE(literal).capacity > 0) {
|
if (TOY_IS_TYPE(literal) && TOY_AS_TYPE(literal).capacity > 0) {
|
||||||
@@ -84,12 +84,8 @@ bool Toy_private_isTruthy(Toy_Literal x) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Toy_Literal Toy_private_toStringLiteral(Toy_RefString* ptr) {
|
|
||||||
return ((Toy_Literal){{ .string = { .ptr = ptr }},TOY_LITERAL_STRING, 0});
|
|
||||||
}
|
|
||||||
|
|
||||||
Toy_Literal Toy_private_toIdentifierLiteral(Toy_RefString* ptr) {
|
Toy_Literal Toy_private_toIdentifierLiteral(Toy_RefString* ptr) {
|
||||||
return ((Toy_Literal){{ .identifier = { .ptr = ptr, .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});
|
||||||
}
|
}
|
||||||
|
|
||||||
Toy_Literal* Toy_private_typePushSubtype(Toy_Literal* lit, Toy_Literal subtype) {
|
Toy_Literal* Toy_private_typePushSubtype(Toy_Literal* lit, Toy_Literal subtype) {
|
||||||
@@ -146,10 +142,8 @@ Toy_Literal Toy_copyLiteral(Toy_Literal original) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case TOY_LITERAL_FUNCTION: {
|
case TOY_LITERAL_FUNCTION: {
|
||||||
unsigned char* buffer = TOY_ALLOCATE(unsigned char, TOY_AS_FUNCTION_BYTECODE_LENGTH(original));
|
Toy_Literal literal = TOY_TO_FUNCTION_LITERAL(Toy_copyRefFunction( TOY_AS_FUNCTION(original).inner.ptr ));
|
||||||
memcpy(buffer, TOY_AS_FUNCTION(original).inner.bytecode, TOY_AS_FUNCTION_BYTECODE_LENGTH(original));
|
|
||||||
|
|
||||||
Toy_Literal literal = TOY_TO_FUNCTION_LITERAL(buffer, TOY_AS_FUNCTION_BYTECODE_LENGTH(original));
|
|
||||||
TOY_AS_FUNCTION(literal).scope = Toy_copyScope(TOY_AS_FUNCTION(original).scope);
|
TOY_AS_FUNCTION(literal).scope = Toy_copyScope(TOY_AS_FUNCTION(original).scope);
|
||||||
|
|
||||||
return literal;
|
return literal;
|
||||||
@@ -378,8 +372,10 @@ int Toy_hashLiteral(Toy_Literal lit) {
|
|||||||
case TOY_LITERAL_INTEGER:
|
case TOY_LITERAL_INTEGER:
|
||||||
return hashUInt((unsigned int)TOY_AS_INTEGER(lit));
|
return hashUInt((unsigned int)TOY_AS_INTEGER(lit));
|
||||||
|
|
||||||
case TOY_LITERAL_FLOAT:
|
case TOY_LITERAL_FLOAT: {
|
||||||
return hashUInt(*(unsigned int*)(&TOY_AS_FLOAT(lit)));
|
unsigned int* ptr = (unsigned int*)(&TOY_AS_FLOAT(lit));
|
||||||
|
return hashUInt(*ptr);
|
||||||
|
}
|
||||||
|
|
||||||
case TOY_LITERAL_STRING:
|
case TOY_LITERAL_STRING:
|
||||||
return hashString(Toy_toCString(TOY_AS_STRING(lit)), Toy_lengthRefString(TOY_AS_STRING(lit)));
|
return hashString(Toy_toCString(TOY_AS_STRING(lit)), Toy_lengthRefString(TOY_AS_STRING(lit)));
|
||||||
@@ -446,7 +442,7 @@ static void printToBuffer(const char* str) {
|
|||||||
globalPrintBuffer = TOY_GROW_ARRAY(char, globalPrintBuffer, oldCapacity, globalPrintCapacity);
|
globalPrintBuffer = TOY_GROW_ARRAY(char, globalPrintBuffer, oldCapacity, globalPrintCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(globalPrintBuffer + globalPrintCount, strlen(str) + 1, "%s", str);
|
snprintf(globalPrintBuffer + globalPrintCount, strlen(str) + 1, "%s", str ? str : "\0");
|
||||||
globalPrintCount += strlen(str);
|
globalPrintCount += strlen(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-20
@@ -3,6 +3,7 @@
|
|||||||
#include "toy_common.h"
|
#include "toy_common.h"
|
||||||
|
|
||||||
#include "toy_refstring.h"
|
#include "toy_refstring.h"
|
||||||
|
#include "toy_reffunction.h"
|
||||||
|
|
||||||
//forward delcare stuff
|
//forward delcare stuff
|
||||||
struct Toy_Literal;
|
struct Toy_Literal;
|
||||||
@@ -55,7 +56,7 @@ typedef struct Toy_Literal {
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
union {
|
union {
|
||||||
void* bytecode; //8
|
Toy_RefFunction* ptr; //8
|
||||||
Toy_NativeFn native; //8
|
Toy_NativeFn native; //8
|
||||||
Toy_HookFn hook; //8
|
Toy_HookFn hook; //8
|
||||||
} inner; //8
|
} inner; //8
|
||||||
@@ -63,12 +64,11 @@ typedef struct Toy_Literal {
|
|||||||
} function; //16
|
} function; //16
|
||||||
|
|
||||||
struct { //for variable names
|
struct { //for variable names
|
||||||
Toy_RefString* ptr; //8
|
Toy_RefString* ptr; //8
|
||||||
int hash; //4
|
int hash; //4
|
||||||
} identifier; //16
|
} identifier; //16
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
||||||
struct Toy_Literal* subtypes; //8
|
struct Toy_Literal* subtypes; //8
|
||||||
Toy_LiteralType typeOf; //4
|
Toy_LiteralType typeOf; //4
|
||||||
unsigned char capacity; //1
|
unsigned char capacity; //1
|
||||||
@@ -80,10 +80,13 @@ typedef struct Toy_Literal {
|
|||||||
void* ptr; //8
|
void* ptr; //8
|
||||||
int tag; //4
|
int tag; //4
|
||||||
} opaque; //16
|
} opaque; //16
|
||||||
|
|
||||||
|
void* generic; //8
|
||||||
} as; //16
|
} as; //16
|
||||||
|
|
||||||
Toy_LiteralType type; //4
|
Toy_LiteralType type; //4
|
||||||
int bytecodeLength; //4 - shenanigans with byte alignment reduces the size of Toy_Literal
|
//4 - unused
|
||||||
|
//shenanigans with byte alignment reduces the size of Toy_Literal
|
||||||
} Toy_Literal;
|
} Toy_Literal;
|
||||||
|
|
||||||
#define TOY_IS_NULL(value) ((value).type == TOY_LITERAL_NULL)
|
#define TOY_IS_NULL(value) ((value).type == TOY_LITERAL_NULL)
|
||||||
@@ -113,29 +116,29 @@ typedef struct Toy_Literal {
|
|||||||
#define TOY_AS_TYPE(value) ((value).as.type)
|
#define TOY_AS_TYPE(value) ((value).as.type)
|
||||||
#define TOY_AS_OPAQUE(value) ((value).as.opaque.ptr)
|
#define TOY_AS_OPAQUE(value) ((value).as.opaque.ptr)
|
||||||
|
|
||||||
#define TOY_TO_NULL_LITERAL ((Toy_Literal){{ .integer = 0 }, TOY_LITERAL_NULL, 0})
|
#define TOY_TO_NULL_LITERAL ((Toy_Literal){{ .integer = 0 }, TOY_LITERAL_NULL})
|
||||||
#define TOY_TO_BOOLEAN_LITERAL(value) ((Toy_Literal){{ .boolean = value }, TOY_LITERAL_BOOLEAN, 0})
|
#define TOY_TO_BOOLEAN_LITERAL(value) ((Toy_Literal){{ .boolean = value }, TOY_LITERAL_BOOLEAN})
|
||||||
#define TOY_TO_INTEGER_LITERAL(value) ((Toy_Literal){{ .integer = value }, TOY_LITERAL_INTEGER, 0})
|
#define TOY_TO_INTEGER_LITERAL(value) ((Toy_Literal){{ .integer = value }, TOY_LITERAL_INTEGER})
|
||||||
#define TOY_TO_FLOAT_LITERAL(value) ((Toy_Literal){{ .number = value }, TOY_LITERAL_FLOAT, 0})
|
#define TOY_TO_FLOAT_LITERAL(value) ((Toy_Literal){{ .number = value }, TOY_LITERAL_FLOAT})
|
||||||
#define TOY_TO_STRING_LITERAL(value) Toy_private_toStringLiteral(value)
|
#define TOY_TO_STRING_LITERAL(value) ((Toy_Literal){{ .string = { .ptr = value }},TOY_LITERAL_STRING})
|
||||||
#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})
|
||||||
#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})
|
||||||
#define TOY_TO_FUNCTION_LITERAL(value, l) ((Toy_Literal){{ .function = { .inner = { .bytecode = value }, .scope = NULL }}, TOY_LITERAL_FUNCTION, l})
|
#define TOY_TO_FUNCTION_LITERAL(value) ((Toy_Literal){{ .function = { .inner = { .ptr = value }, .scope = NULL }}, TOY_LITERAL_FUNCTION})
|
||||||
#define TOY_TO_FUNCTION_NATIVE_LITERAL(value) ((Toy_Literal){{ .function = { .inner = { .native = value }, .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})
|
||||||
#define TOY_TO_FUNCTION_HOOK_LITERAL(value) ((Toy_Literal){{ .function = { .inner = { .hook = value }, .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})
|
||||||
#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, .constant = c, .subtypes = NULL, .capacity = 0, .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})
|
||||||
#define TOY_TO_OPAQUE_LITERAL(value, t) ((Toy_Literal){{ .opaque = { .ptr = value, .tag = t }}, TOY_LITERAL_OPAQUE, 0})
|
#define TOY_TO_OPAQUE_LITERAL(value, t) ((Toy_Literal){{ .opaque = { .ptr = value, .tag = t }}, TOY_LITERAL_OPAQUE})
|
||||||
|
|
||||||
//BUGFIX: For blank indexing
|
//BUGFIX: For blank indexing
|
||||||
#define TOY_IS_INDEX_BLANK(value) ((value).type == TOY_LITERAL_INDEX_BLANK)
|
#define TOY_IS_INDEX_BLANK(value) ((value).type == TOY_LITERAL_INDEX_BLANK)
|
||||||
#define TOY_TO_INDEX_BLANK_LITERAL ((Toy_Literal){{ .integer = 0 }, TOY_LITERAL_INDEX_BLANK, 0})
|
#define TOY_TO_INDEX_BLANK_LITERAL ((Toy_Literal){{ .integer = 0 }, TOY_LITERAL_INDEX_BLANK})
|
||||||
|
|
||||||
TOY_API void Toy_freeLiteral(Toy_Literal literal);
|
TOY_API void Toy_freeLiteral(Toy_Literal literal);
|
||||||
|
|
||||||
#define TOY_IS_TRUTHY(x) Toy_private_isTruthy(x)
|
#define TOY_IS_TRUTHY(x) Toy_private_isTruthy(x)
|
||||||
|
|
||||||
#define TOY_AS_FUNCTION_BYTECODE_LENGTH(lit) ((lit).bytecodeLength)
|
#define TOY_AS_FUNCTION_BYTECODE_LENGTH(lit) (Toy_lengthRefFunction((lit).inner.ptr))
|
||||||
|
|
||||||
#define TOY_MAX_STRING_LENGTH 4096
|
#define TOY_MAX_STRING_LENGTH 4096
|
||||||
#define TOY_HASH_I(lit) ((lit).as.identifier.hash)
|
#define TOY_HASH_I(lit) ((lit).as.identifier.hash)
|
||||||
@@ -144,7 +147,6 @@ TOY_API void Toy_freeLiteral(Toy_Literal literal);
|
|||||||
|
|
||||||
//BUGFIX: macros are not functions
|
//BUGFIX: macros are not functions
|
||||||
TOY_API bool Toy_private_isTruthy(Toy_Literal x);
|
TOY_API bool Toy_private_isTruthy(Toy_Literal x);
|
||||||
TOY_API Toy_Literal Toy_private_toStringLiteral(Toy_RefString* ptr);
|
|
||||||
TOY_API Toy_Literal Toy_private_toIdentifierLiteral(Toy_RefString* ptr);
|
TOY_API Toy_Literal Toy_private_toIdentifierLiteral(Toy_RefString* ptr);
|
||||||
TOY_API Toy_Literal* Toy_private_typePushSubtype(Toy_Literal* lit, Toy_Literal subtype);
|
TOY_API Toy_Literal* Toy_private_typePushSubtype(Toy_Literal* lit, Toy_Literal subtype);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "toy_memory.h"
|
#include "toy_memory.h"
|
||||||
#include "toy_refstring.h"
|
#include "toy_refstring.h"
|
||||||
|
#include "toy_reffunction.h"
|
||||||
|
|
||||||
#include "toy_console_colors.h"
|
#include "toy_console_colors.h"
|
||||||
|
|
||||||
@@ -49,4 +50,5 @@ void Toy_setMemoryAllocator(Toy_MemoryAllocatorFn fn) {
|
|||||||
|
|
||||||
allocator = fn;
|
allocator = fn;
|
||||||
Toy_setRefStringAllocatorFn(fn);
|
Toy_setRefStringAllocatorFn(fn);
|
||||||
|
Toy_setRefFunctionAllocatorFn(fn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#include "toy_reffunction.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
//memory allocation
|
||||||
|
extern void* Toy_private_defaultMemoryAllocator(void* pointer, size_t oldSize, size_t newSize);
|
||||||
|
static Toy_RefFunctionAllocatorFn allocate = Toy_private_defaultMemoryAllocator;
|
||||||
|
|
||||||
|
void Toy_setRefFunctionAllocatorFn(Toy_RefFunctionAllocatorFn allocator) {
|
||||||
|
allocate = allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
//API
|
||||||
|
Toy_RefFunction* Toy_createRefFunction(const void* data, size_t length) {
|
||||||
|
//allocate the memory area (including metadata space)
|
||||||
|
Toy_RefFunction* refFunction = allocate(NULL, 0, sizeof(size_t) + sizeof(int) + sizeof(char) * length);
|
||||||
|
|
||||||
|
if (refFunction == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set the data
|
||||||
|
refFunction->refCount = 1;
|
||||||
|
refFunction->length = length;
|
||||||
|
memcpy(refFunction->data, data, refFunction->length);
|
||||||
|
|
||||||
|
return refFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Toy_deleteRefFunction(Toy_RefFunction* refFunction) {
|
||||||
|
//decrement, then check
|
||||||
|
refFunction->refCount--;
|
||||||
|
if (refFunction->refCount <= 0) {
|
||||||
|
allocate(refFunction, sizeof(size_t) + sizeof(int) + sizeof(char) * (refFunction->length + 1), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Toy_countRefFunction(Toy_RefFunction* refFunction) {
|
||||||
|
return refFunction->refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Toy_lengthRefFunction(Toy_RefFunction* refFunction) {
|
||||||
|
return refFunction->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_RefFunction* Toy_copyRefFunction(Toy_RefFunction* refFunction) {
|
||||||
|
//Cheaty McCheater Face
|
||||||
|
refFunction->refCount++;
|
||||||
|
return refFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_RefFunction* Toy_deepCopyRefFunction(Toy_RefFunction* refFunction) {
|
||||||
|
//create a new function, with a new refCount
|
||||||
|
return Toy_createRefFunction(refFunction->data, refFunction->length);
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "toy_common.h"
|
||||||
|
|
||||||
|
//memory allocation hook
|
||||||
|
typedef void* (*Toy_RefFunctionAllocatorFn)(void* pointer, size_t oldSize, size_t newSize);
|
||||||
|
TOY_API void Toy_setRefFunctionAllocatorFn(Toy_RefFunctionAllocatorFn);
|
||||||
|
|
||||||
|
//the RefFunction structure
|
||||||
|
typedef struct Toy_RefFunction {
|
||||||
|
size_t length;
|
||||||
|
int refCount;
|
||||||
|
unsigned char data[];
|
||||||
|
} Toy_RefFunction;
|
||||||
|
|
||||||
|
//API
|
||||||
|
TOY_API Toy_RefFunction* Toy_createRefFunction(const void* data, size_t length);
|
||||||
|
TOY_API void Toy_deleteRefFunction(Toy_RefFunction* refFunction);
|
||||||
|
TOY_API int Toy_countRefFunction(Toy_RefFunction* refFunction);
|
||||||
|
TOY_API size_t Toy_lengthRefFunction(Toy_RefFunction* refFunction);
|
||||||
|
TOY_API Toy_RefFunction* Toy_copyRefFunction(Toy_RefFunction* refFunction);
|
||||||
|
TOY_API Toy_RefFunction* Toy_deepCopyRefFunction(Toy_RefFunction* refFunction);
|
||||||
|
|
||||||
Reference in New Issue
Block a user