diff --git a/src/dusk/script/vm/execute/scriptvmframe.h b/src/dusk/script/vm/execute/scriptvmframe.h new file mode 100644 index 00000000..0ed7a974 --- /dev/null +++ b/src/dusk/script/vm/execute/scriptvmframe.h @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once + +#include "scripttypes.h" + +typedef struct scriptvmimage_s scriptvmimage_t; +typedef struct scriptvmfunction_s scriptvmfunction_t; + +// A function that is running. It is on the C stack, which is where the collector +// finds its scope. Its variables and its stack are in the block of values of the +// coroutine, which the collector looks through as far as it is used. +typedef struct scriptvmframe_s { + scriptruntime_t *runtime; + const scriptvmimage_t *image; + const scriptvmfunction_t *function; + const uint8_t *code; + const uint8_t *pc; + const uint8_t *opStart; + scriptvalue_t *locals; + scriptvalue_t *stack; + uint16_t stackCapacity; + uint16_t sp; + bool done; + scriptvalue_t result; +} scriptvmframe_t; diff --git a/src/dusk/script/vm/execute/scriptvmfunction.h b/src/dusk/script/vm/execute/scriptvmfunction.h index 28aa48a3..f3c889af 100644 --- a/src/dusk/script/vm/execute/scriptvmfunction.h +++ b/src/dusk/script/vm/execute/scriptvmfunction.h @@ -7,7 +7,30 @@ #pragma once -#include "scriptvmtypes.h" +#include "scripttypes.h" + +typedef struct scriptvmimage_s scriptvmimage_t; +typedef struct scriptvmframe_s scriptvmframe_t; + +// Bits of a loaded function's flags, see scriptvmfunction_t. +#define SCRIPT_VM_FUNCTION_FLAG_ASYNC (1 << 0) // declared async, see SCRIPT_BINARY_FLAG_ASYNC +#define SCRIPT_VM_FUNCTION_FLAG_ROOT (1 << 1) // the main script, not an include +#define SCRIPT_VM_FUNCTION_FLAG_SCRIPT (1 << 2) // function 0, what a script runs from + +// One function of a loaded compiled script. +typedef struct scriptvmfunction_s { + const scriptvmimage_t *image; + char name[SCRIPT_NAME_MAX]; + uint8_t paramCount; + uint8_t localCount; + uint8_t stackMax; + uint8_t flags; // SCRIPT_VM_FUNCTION_FLAG_* + uint16_t line; + uint16_t column; + uint16_t body; + uint16_t paramDefault[SCRIPT_PARAMS_MAX]; + const char **localName; // from the map, NULL without one +} scriptvmfunction_t; /** * The executor of the virtual machine, the functions it makes point at it. diff --git a/src/dusk/script/vm/execute/scriptvmname.h b/src/dusk/script/vm/execute/scriptvmname.h index 146154fd..b722c073 100644 --- a/src/dusk/script/vm/execute/scriptvmname.h +++ b/src/dusk/script/vm/execute/scriptvmname.h @@ -7,7 +7,21 @@ #pragma once -#include "scriptvmtypes.h" +#include "scripttypes.h" + +typedef struct scriptvmframe_s scriptvmframe_t; + +// What a name of the script is, for the names that are the name of a variable that is +// not a variable of a function: a global, or a built in function, or one of the +// script's own when it is an include. They are found when the script loads and a +// pointer to each variable is kept, so an instruction that has the name has the +// variable too. Eight bytes on purpose, an array of these is indexed with a shift. +typedef struct { + scriptvariable_t *variable; + uint8_t own; // the script declares it at its top level, while loading + uint8_t used; // an instruction has it as the name of a variable, while loading + uint16_t padding; +} scriptvmname_t; /** * The variable an instruction has the name of, which was found when the script loaded. diff --git a/src/dusk/script/vm/execute/scriptvmtable.h b/src/dusk/script/vm/execute/scriptvmtable.h index 7cf67005..f5d8d0d9 100644 --- a/src/dusk/script/vm/execute/scriptvmtable.h +++ b/src/dusk/script/vm/execute/scriptvmtable.h @@ -7,7 +7,12 @@ #pragma once -#include "scriptvmtypes.h" +#include "scripttypes.h" +#include "bytecode/scriptbytecode.h" +#include "execute/scriptvmframe.h" + +// Runs one instruction, the operands are read from the code after it. +typedef void (*scriptvmhandler_t)(scriptvmframe_t *frame); /** * What runs each instruction, indexed by the instruction. diff --git a/src/dusk/script/vm/image/scriptvmimage.h b/src/dusk/script/vm/image/scriptvmimage.h new file mode 100644 index 00000000..249fcf46 --- /dev/null +++ b/src/dusk/script/vm/image/scriptvmimage.h @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once + +#include "scripttypes.h" +#include "execute/scriptvmfunction.h" +#include "execute/scriptvmname.h" + +// A compiled script that has been loaded. The code and the text of the names +// stay inside the bytes the script came in. +struct scriptvmimage_s { + const uint8_t *code; + uint16_t codeSize; + const uint8_t *positions; + uint16_t positionSize; + uint16_t stringCount; + const char **strings; + uint16_t *stringLength; + scriptstring_t **stringCache; + scriptvmname_t *names; + uint16_t functionCount; + scriptvmfunction_t *functions; + scriptsource_t *source; + scriptscope_t *privateScope; // the top level variables of an include +}; diff --git a/src/dusk/script/vm/scriptvmtypes.h b/src/dusk/script/vm/scriptvmtypes.h index 9fa86917..6b7b07cd 100644 --- a/src/dusk/script/vm/scriptvmtypes.h +++ b/src/dusk/script/vm/scriptvmtypes.h @@ -8,80 +8,13 @@ #pragma once // The types of the bytecode virtual machine, on top of the types every part of -// dusk script shares. +// dusk script shares. Each one is defined next to the functions that work with +// it, this just re-includes all of them for the files that reach into more +// than one. #include "scripttypes.h" -#include "bytecode/scriptbytecode.h" - -typedef struct scriptvmimage_s scriptvmimage_t; - -// Bits of a loaded function's flags, see scriptvmfunction_t. -#define SCRIPT_VM_FUNCTION_FLAG_ASYNC (1 << 0) // declared async, see SCRIPT_BINARY_FLAG_ASYNC -#define SCRIPT_VM_FUNCTION_FLAG_ROOT (1 << 1) // the main script, not an include -#define SCRIPT_VM_FUNCTION_FLAG_SCRIPT (1 << 2) // function 0, what a script runs from - -// One function of a loaded compiled script. -typedef struct { - const scriptvmimage_t *image; - char name[SCRIPT_NAME_MAX]; - uint8_t paramCount; - uint8_t localCount; - uint8_t stackMax; - uint8_t flags; // SCRIPT_VM_FUNCTION_FLAG_* - uint16_t line; - uint16_t column; - uint16_t body; - uint16_t paramDefault[SCRIPT_PARAMS_MAX]; - const char **localName; // from the map, NULL without one -} scriptvmfunction_t; - -// What a name of the script is, for the names that are the name of a variable that is -// not a variable of a function: a global, or a built in function, or one of the -// script's own when it is an include. They are found when the script loads and a -// pointer to each variable is kept, so an instruction that has the name has the -// variable too. Eight bytes on purpose, an array of these is indexed with a shift. -typedef struct { - scriptvariable_t *variable; - uint8_t own; // the script declares it at its top level, while loading - uint8_t used; // an instruction has it as the name of a variable, while loading - uint16_t padding; -} scriptvmname_t; - -// A compiled script that has been loaded. The code and the text of the names -// stay inside the bytes the script came in. -struct scriptvmimage_s { - const uint8_t *code; - uint16_t codeSize; - const uint8_t *positions; - uint16_t positionSize; - uint16_t stringCount; - const char **strings; - uint16_t *stringLength; - scriptstring_t **stringCache; - scriptvmname_t *names; - uint16_t functionCount; - scriptvmfunction_t *functions; - scriptsource_t *source; - scriptscope_t *privateScope; // the top level variables of an include -}; - -// A function that is running. It is on the C stack, which is where the collector -// finds its scope. Its variables and its stack are in the block of values of the -// coroutine, which the collector looks through as far as it is used. -typedef struct { - scriptruntime_t *runtime; - const scriptvmimage_t *image; - const scriptvmfunction_t *function; - const uint8_t *code; - const uint8_t *pc; - const uint8_t *opStart; - scriptvalue_t *locals; - scriptvalue_t *stack; - uint16_t stackCapacity; - uint16_t sp; - bool done; - scriptvalue_t result; -} scriptvmframe_t; - -// Runs one instruction, the operands are read from the code after it. -typedef void (*scriptvmhandler_t)(scriptvmframe_t *frame); +#include "execute/scriptvmfunction.h" +#include "execute/scriptvmname.h" +#include "execute/scriptvmframe.h" +#include "execute/scriptvmtable.h" +#include "image/scriptvmimage.h" diff --git a/src/duskscriptcc/compile/builder/scriptbuilderlabel.h b/src/duskscriptcc/compile/builder/scriptbuilderlabel.h index f395319b..3097654d 100644 --- a/src/duskscriptcc/compile/builder/scriptbuilderlabel.h +++ b/src/duskscriptcc/compile/builder/scriptbuilderlabel.h @@ -7,7 +7,18 @@ #pragma once -#include "scriptcompiletypes.h" +#include "core/scriptcore.h" +#include "bytecode/scriptbytecode.h" + +typedef struct scriptbuilder_s scriptbuilder_t; + +// A place in the code that jumps point at. Jumps made before the place is known +// are chained through the code itself, each one holds where the one before it is, +// and scriptBuilderPlace fills them all in. +typedef struct scriptlabel_s { + uint16_t head; + int32_t target; +} scriptlabel_t; /** * Makes a label that has not been placed yet. diff --git a/src/duskscriptcc/compile/scriptbuilder.h b/src/duskscriptcc/compile/scriptbuilder.h new file mode 100644 index 00000000..e9b69102 --- /dev/null +++ b/src/duskscriptcc/compile/scriptbuilder.h @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once + +#include "scriptcompiletypes.h" +#include "scriptcompile.h" +#include "statement/scriptcompileloopcontext.h" + +typedef struct scriptlabel_s scriptlabel_t; + +// Everything the compiler has put together so far. +typedef struct scriptbuilder_s { + scriptruntime_t *runtime; + const scriptsource_t *source; + scriptincluderesolver_t resolver; + void *resolverData; + + // The natives that have a signature, which are called by their number, unless the script + // can change what their name is: the names it declares, assigns or counts. When there are + // more of those than room for, none is called by its number. + const scriptnativetable_t *natives; + const char *taintName[SCRIPT_COMPILE_TAINT_MAX]; + uint16_t taintLength[SCRIPT_COMPILE_TAINT_MAX]; + uint8_t taintCount; + bool taintAll; + + uint8_t *code; + uint32_t codeLength; + + // The last instruction written, so it can be joined with the one after it. + // Nothing is joined across a label, code can arrive there from anywhere. + int16_t lastOp; + uint32_t lastOpStart; + int16_t prevOp; + uint32_t prevOpStart; + int16_t prev2Op; + uint32_t prev2OpStart; + + // The last place that was written to the list of positions, and how the list was + // before it, so it can be moved when the code it belongs to is joined with the + // code before it. + bool placeValid; + uint16_t placeOffset; + uint16_t placeLine; + uint16_t placeColumn; + uint32_t beforePlaceBytes; + uint16_t beforePlaceOffset; + uint16_t beforePlaceLine; + + uint8_t *positions; + uint32_t positionBytes; + uint16_t positionOffset; + uint16_t positionLine; + + char *strings; + uint32_t stringBytes; + uint16_t stringOffset[SCRIPT_COMPILE_STRINGS_MAX]; + uint16_t stringLength[SCRIPT_COMPILE_STRINGS_MAX]; + uint16_t stringCount; + uint16_t sourceName; + + const scriptfuncnode_t *functionNodes[SCRIPT_COMPILE_FUNCTIONS_MAX]; + uint16_t functionName[SCRIPT_COMPILE_FUNCTIONS_MAX]; + uint16_t functionBody[SCRIPT_COMPILE_FUNCTIONS_MAX]; + uint8_t functionLocals[SCRIPT_COMPILE_FUNCTIONS_MAX]; + uint8_t functionStack[SCRIPT_COMPILE_FUNCTIONS_MAX]; + uint16_t functionLocalNames[SCRIPT_COMPILE_FUNCTIONS_MAX][SCRIPT_COMPILE_LOCALS_MAX]; + uint16_t functionDefaults[SCRIPT_COMPILE_FUNCTIONS_MAX][SCRIPT_PARAMS_MAX]; + uint16_t functionCount; + + // The function being compiled. + int32_t stackDepth; + int32_t stackMax; + uint16_t current; + scriptloopcontext_t loops[SCRIPT_COMPILE_LOOPS_MAX]; + uint8_t loopCount; + + // Calls of small functions that are made in place, see scriptcompileinline.c: whether they are, which + // functions are being made in place now, and where a return of one goes + const scriptfuncnode_t *inlineStack[SCRIPT_COMPILE_INLINE_DEPTH]; + uint8_t inlineDepth; + scriptlabel_t *inlineEnd; + uint8_t inlineResult; + uint32_t inlineGrowth; // bytes of code that calls made in place have added + bool inlineReport; // says what was decided for every call, DUSK_INLINE_REPORT in the environment + uint8_t resolveFloor; + + // The variables that can be seen right now: their names and numbers, and + // where each block of them starts. + uint16_t visibleName[SCRIPT_COMPILE_LOCALS_MAX]; + uint8_t visibleSlot[SCRIPT_COMPILE_LOCALS_MAX]; + uint8_t visibleCount; + uint8_t blockStart[SCRIPT_COMPILE_BLOCKS_MAX]; + uint8_t blockDepth; + uint8_t localCount; + uint8_t localHigh; // the most variables there have been at once, which is how many the function has + + // Where the interpreter would say it is, and where the code last said it was. + // Positions are only written out right before an instruction that can fail. + uint16_t line; + uint16_t column; + uint16_t lastLine; + uint16_t lastColumn; + bool lastKnown; +} scriptbuilder_t; diff --git a/src/duskscriptcc/compile/scriptcompile.h b/src/duskscriptcc/compile/scriptcompile.h index 3ca36376..d3ceba9b 100644 --- a/src/duskscriptcc/compile/scriptcompile.h +++ b/src/duskscriptcc/compile/scriptcompile.h @@ -7,6 +7,23 @@ #pragma once +#include "core/scriptcore.h" + +/** + * Works out which asset a path in an include is. A script that is compiled while the + * resolver is set has the path in include("lib/util.ds") written to it as the number + * of the asset, so it does not have to be found by its path while it runs. + * + * @param data What setting the resolver was given. + * @param from The name of the script that has the include. + * @param path The path as it is written in the include. + * @returns The asset number, or -1 when there is no such script. + */ +typedef int32_t (*scriptincluderesolver_t)(void *data, const char *from, const char *path); + +// scriptnativetable_t, scripterror_t and scriptresult_t, used below, come from +// here - after scriptincluderesolver_t, which scriptbuilder_t needs and which +// this pulls in by way of scriptcompiletypes.h -> scriptbuilder.h. #include "scriptcompiletypes.h" /** @@ -32,19 +49,8 @@ void scriptCompileSetNatives(const scriptnativetable_t *table); * Compiles dusk script source into a compiled script, the .dsb a virtual machine * runs. This is the compile half of the API, it is what runs on the host before a * script ships. Syntax errors, and anything too big for the format, are reported - * the same way the interpreter reports them. - * - * @param name Name of the script, shown in errors and stack traces. - * @param source Null terminated dusk script source. - * @param rootAsync Whether await can be used at the top level. - * @param bytecode Buffer the compiled script is written to. - * @param capacity Size of the buffer in bytes. - * @param size Receives the number of bytes written to the buffer. - * @param error Receives details when compiling fails, may be NULL. - * @returns SCRIPT_OK on success, otherwise the kind of error. - */ -/** - * Compiles a script. The map, which is what errors are told with, is another file: names and places in the source. + * the same way the interpreter reports them. The map, which is what errors are + * told with, is another file: names and places in the source. * * @param name The name of the script, as it is in errors. * @param source The text of the script. diff --git a/src/duskscriptcc/compile/scriptcompiletypes.h b/src/duskscriptcc/compile/scriptcompiletypes.h index f02712a5..302c35a5 100644 --- a/src/duskscriptcc/compile/scriptcompiletypes.h +++ b/src/duskscriptcc/compile/scriptcompiletypes.h @@ -8,24 +8,14 @@ #pragma once // The types of the compiler, on top of what the parser and the shared runtime -// have. +// have, and the limits of the format it compiles to. scriptbuilder_t, the +// type every file here reaches into, is defined in scriptbuilder.h; this just +// re-includes that and the rest for the files that need more than one. #include "scriptparsetypes.h" #include "bytecode/scriptbytecode.h" #include "builtin/scriptnativesig.h" -/** - * Works out which asset a path in an include is. A script that is compiled while the - * resolver is set has the path in include("lib/util.ds") written to it as the number - * of the asset, so it does not have to be found by its path while it runs. - * - * @param data What setting the resolver was given. - * @param from The name of the script that has the include. - * @param path The path as it is written in the include. - * @returns The asset number, or -1 when there is no such script. - */ -typedef int32_t (*scriptincluderesolver_t)(void *data, const char *from, const char *path); - #define SCRIPT_COMPILE_CODE_MAX 65534 #define SCRIPT_COMPILE_STRINGS_MAX 1024 #define SCRIPT_COMPILE_STRING_BYTES 32768 @@ -53,112 +43,4 @@ typedef int32_t (*scriptincluderesolver_t)(void *data, const char *from, const c #define SCRIPT_COMPILE_BY_NAME 0xFF #define SCRIPT_COMPILE_REDECLARED 0xFE -// A place in the code that jumps point at. Jumps made before the place is known -// are chained through the code itself, each one holds where the one before it is, -// and scriptBuilderPlace fills them all in. -typedef struct { - uint16_t head; - int32_t target; -} scriptlabel_t; - -// What break and continue jump to. A switch has no continue label. -typedef struct { - scriptlabel_t *breakLabel; - scriptlabel_t *continueLabel; -} scriptloopcontext_t; - -// Everything the compiler has put together so far. -typedef struct { - scriptruntime_t *runtime; - const scriptsource_t *source; - scriptincluderesolver_t resolver; - void *resolverData; - - // The natives that have a signature, which are called by their number, unless the script - // can change what their name is: the names it declares, assigns or counts. When there are - // more of those than room for, none is called by its number. - const scriptnativetable_t *natives; - const char *taintName[SCRIPT_COMPILE_TAINT_MAX]; - uint16_t taintLength[SCRIPT_COMPILE_TAINT_MAX]; - uint8_t taintCount; - bool taintAll; - - uint8_t *code; - uint32_t codeLength; - - // The last instruction written, so it can be joined with the one after it. - // Nothing is joined across a label, code can arrive there from anywhere. - int16_t lastOp; - uint32_t lastOpStart; - int16_t prevOp; - uint32_t prevOpStart; - int16_t prev2Op; - uint32_t prev2OpStart; - - // The last place that was written to the list of positions, and how the list was - // before it, so it can be moved when the code it belongs to is joined with the - // code before it. - bool placeValid; - uint16_t placeOffset; - uint16_t placeLine; - uint16_t placeColumn; - uint32_t beforePlaceBytes; - uint16_t beforePlaceOffset; - uint16_t beforePlaceLine; - - uint8_t *positions; - uint32_t positionBytes; - uint16_t positionOffset; - uint16_t positionLine; - - char *strings; - uint32_t stringBytes; - uint16_t stringOffset[SCRIPT_COMPILE_STRINGS_MAX]; - uint16_t stringLength[SCRIPT_COMPILE_STRINGS_MAX]; - uint16_t stringCount; - uint16_t sourceName; - - const scriptfuncnode_t *functionNodes[SCRIPT_COMPILE_FUNCTIONS_MAX]; - uint16_t functionName[SCRIPT_COMPILE_FUNCTIONS_MAX]; - uint16_t functionBody[SCRIPT_COMPILE_FUNCTIONS_MAX]; - uint8_t functionLocals[SCRIPT_COMPILE_FUNCTIONS_MAX]; - uint8_t functionStack[SCRIPT_COMPILE_FUNCTIONS_MAX]; - uint16_t functionLocalNames[SCRIPT_COMPILE_FUNCTIONS_MAX][SCRIPT_COMPILE_LOCALS_MAX]; - uint16_t functionDefaults[SCRIPT_COMPILE_FUNCTIONS_MAX][SCRIPT_PARAMS_MAX]; - uint16_t functionCount; - - // The function being compiled. - int32_t stackDepth; - int32_t stackMax; - uint16_t current; - scriptloopcontext_t loops[SCRIPT_COMPILE_LOOPS_MAX]; - uint8_t loopCount; - - // Calls of small functions that are made in place, see scriptcompileinline.c: whether they are, which - // functions are being made in place now, and where a return of one goes - const scriptfuncnode_t *inlineStack[SCRIPT_COMPILE_INLINE_DEPTH]; - uint8_t inlineDepth; - scriptlabel_t *inlineEnd; - uint8_t inlineResult; - uint32_t inlineGrowth; // bytes of code that calls made in place have added - bool inlineReport; // says what was decided for every call, DUSK_INLINE_REPORT in the environment - uint8_t resolveFloor; - - // The variables that can be seen right now: their names and numbers, and - // where each block of them starts. - uint16_t visibleName[SCRIPT_COMPILE_LOCALS_MAX]; - uint8_t visibleSlot[SCRIPT_COMPILE_LOCALS_MAX]; - uint8_t visibleCount; - uint8_t blockStart[SCRIPT_COMPILE_BLOCKS_MAX]; - uint8_t blockDepth; - uint8_t localCount; - uint8_t localHigh; // the most variables there have been at once, which is how many the function has - - // Where the interpreter would say it is, and where the code last said it was. - // Positions are only written out right before an instruction that can fail. - uint16_t line; - uint16_t column; - uint16_t lastLine; - uint16_t lastColumn; - bool lastKnown; -} scriptbuilder_t; +#include "scriptbuilder.h" diff --git a/src/duskscriptcc/compile/statement/scriptcompileloopcontext.h b/src/duskscriptcc/compile/statement/scriptcompileloopcontext.h index 6a0441f7..4ee9d7ef 100644 --- a/src/duskscriptcc/compile/statement/scriptcompileloopcontext.h +++ b/src/duskscriptcc/compile/statement/scriptcompileloopcontext.h @@ -7,7 +7,16 @@ #pragma once -#include "scriptcompiletypes.h" +#include "core/scriptcore.h" + +typedef struct scriptbuilder_s scriptbuilder_t; +typedef struct scriptlabel_s scriptlabel_t; + +// What break and continue jump to. A switch has no continue label. +typedef struct { + scriptlabel_t *breakLabel; + scriptlabel_t *continueLabel; +} scriptloopcontext_t; /** * Starts a loop or switch that break and continue can jump out of. diff --git a/src/duskscriptcc/parse/parser/scriptfuncnode.h b/src/duskscriptcc/parse/parser/scriptfuncnode.h new file mode 100644 index 00000000..b2607524 --- /dev/null +++ b/src/duskscriptcc/parse/parser/scriptfuncnode.h @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once + +#include "core/scriptcore.h" +#include "core/scriptsource.h" +#include "parser/scriptnode.h" + +typedef struct { + char name[SCRIPT_NAME_MAX]; + scriptnode_t *defaultValue; +} scriptparam_t; + +// Bits of a function's flags, see scriptfuncnode_t. +#define SCRIPT_FUNCNODE_FLAG_ASYNC (1 << 0) +#define SCRIPT_FUNCNODE_FLAG_INLINE (1 << 1) // declared with inline, which is made in place of every call it can be +#define SCRIPT_FUNCNODE_FLAG_NOINLINE (1 << 2) // declared with noinline, which is never made in place +#define SCRIPT_FUNCNODE_FLAG_ROOT (1 << 3) +#define SCRIPT_FUNCNODE_FLAG_SCRIPT (1 << 4) // the top level of a script, which is not a function that was written in it + +typedef struct scriptfuncnode_s { + char name[SCRIPT_NAME_MAX]; + scriptparam_t params[SCRIPT_PARAMS_MAX]; + uint8_t paramCount; + scriptnode_t *body; + uint8_t flags; // SCRIPT_FUNCNODE_FLAG_* + uint16_t uses; // how many times its name is used in the script, a function that is used once is made in place + uint16_t line; + uint16_t column; + const scriptsource_t *source; +} scriptfuncnode_t; diff --git a/src/duskscriptcc/parse/parser/scriptnode.h b/src/duskscriptcc/parse/parser/scriptnode.h index 81380e7e..c3a8a3a0 100644 --- a/src/duskscriptcc/parse/parser/scriptnode.h +++ b/src/duskscriptcc/parse/parser/scriptnode.h @@ -12,6 +12,7 @@ #include "core/scriptsource.h" typedef struct scriptruntime_s scriptruntime_t; +typedef struct scriptfuncnode_s scriptfuncnode_t; typedef enum { SCRIPT_NODE_BLOCK, @@ -48,8 +49,6 @@ typedef enum { SCRIPT_NODE_AWAIT } scriptnodekind_t; -struct scriptfuncnode_s; - // One node of the syntax tree. What a, b, c and d mean depends on the kind, see // the parser. typedef struct scriptnode_s { @@ -67,33 +66,14 @@ typedef struct scriptnode_s { float numberValue; // a SCRIPT_NODE_NUMBER literal's value const char *text; uint16_t length; - struct scriptfuncnode_s *function; + scriptfuncnode_t *function; // Set when the value of the node is known when the script is parsed: the literal of the constant it is, or // that a name, an index or a member of one is. A node that has it is not assigned to. const struct scriptnode_s *constant; void *cache; } scriptnode_t; -typedef struct { - char name[SCRIPT_NAME_MAX]; - scriptnode_t *defaultValue; -} scriptparam_t; - -// Bits of a function's flags, see scriptfuncnode_t. -#define SCRIPT_FUNCNODE_FLAG_ASYNC (1 << 0) -#define SCRIPT_FUNCNODE_FLAG_INLINE (1 << 1) // declared with inline, which is made in place of every call it can be -#define SCRIPT_FUNCNODE_FLAG_NOINLINE (1 << 2) // declared with noinline, which is never made in place -#define SCRIPT_FUNCNODE_FLAG_ROOT (1 << 3) -#define SCRIPT_FUNCNODE_FLAG_SCRIPT (1 << 4) // the top level of a script, which is not a function that was written in it - -typedef struct scriptfuncnode_s { - char name[SCRIPT_NAME_MAX]; - scriptparam_t params[SCRIPT_PARAMS_MAX]; - uint8_t paramCount; - scriptnode_t *body; - uint8_t flags; // SCRIPT_FUNCNODE_FLAG_* - uint16_t uses; // how many times its name is used in the script, a function that is used once is made in place - uint16_t line; - uint16_t column; - const scriptsource_t *source; -} scriptfuncnode_t; +// scriptfuncnode_t, a function declaration (what node->function points at when +// kind is SCRIPT_NODE_FUNCDECL or SCRIPT_NODE_FUNCTION), is defined in its own +// file; this re-includes it for the files that reach into both. +#include "parser/scriptfuncnode.h"