mirror of https://gitlab.com/nakst/essence
scripting engine add list literals
This commit is contained in:
parent
f14586d2fa
commit
cbb303c1e3
|
@ -182,121 +182,41 @@ void Start() {
|
|||
|
||||
// Set environment variables to force configure scripts to assume the unrecognised cross-compile target is okay.
|
||||
if !buildCross {
|
||||
SystemSetEnvironmentVariable("ac_cv_func_calloc_0_nonnull", "yes");
|
||||
SystemSetEnvironmentVariable("ac_cv_func_chown_works", "yes");
|
||||
SystemSetEnvironmentVariable("ac_cv_func_getgroups_works", "yes");
|
||||
SystemSetEnvironmentVariable("ac_cv_func_malloc_0_nonnull", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_cbrtl_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_ceil_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_ceilf_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_ceill_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_chown_ctime_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_chown_slash_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_exp2l_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_expm1_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_fcntl_f_dupfd_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_fdopendir_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_floorf_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_fma_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_fmaf_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_fmal_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_fmod_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_fmodf_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_fmodl_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_fpurge_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_futimens_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_futimesat_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_getgroups_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_gettimeofday_clobber", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_hypot_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_hypotf_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_hypotl_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_isfinitel_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_isnanl_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_link_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_linkat_slash", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_log10_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_log10f_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_log1p_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_log1pf_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_log1pl_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_log2_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_log2f_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_log_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_logf_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_lstat_dereferences_slashed_symlink", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_mbrlen_empty_input", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_mbrtowc_empty_input", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_memchr_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_memmem_works_fast", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_mkdir_trailing_dot_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_mkdir_trailing_slash_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_mkfifo_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_mknod_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_modf_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_modff_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_modfl_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_nanosleep", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_open_directory_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_perror_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_printf_directive_a", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_printf_directive_f", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_printf_directive_n", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_printf_enomem", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_printf_flag_zero", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_printf_infinite", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_printf_infinite_long_double", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_printf_sizes_c99", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_pselect_detects_ebadf", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_ptsname_sets_errno", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_readlink_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_realpath_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_remainder_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_remainderf_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_remainderl_iee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_rename_dest_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_rename_link_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_rename_slash_dst_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_rename_slash_src_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_rmdir_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_round_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_roundf_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_select_detects_ebadf", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_setenv_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_signbit", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_signbit_gcc", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_sleep_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_snprintf_directive_n", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_snprintf_retval_c99", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_snprintf_truncation_c99", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_stat_dir_slash", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_stat_file_slash", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_stpncpy", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_strcasestr_linear", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_strchrnul_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_strerror_0_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_strstr_linear", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_strtod_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_svid_putenv", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_symlink_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_tdelete_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_trunc_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_truncf_ieee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_truncl_iee", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_tzset_clobber", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_ungetc_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_unlink_honors_slashes", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_unsetenv_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_usleep_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_utimensat_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_vsnprintf_posix", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_vsnprintf_zerosize_c99", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_vsprintf_posix", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_wcwidth_works", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_working_getdelim", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_working_mkstemp", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_working_mktime", "yes");
|
||||
SystemSetEnvironmentVariable("gl_cv_func_working_strerror", "yes");
|
||||
str[] variables = [
|
||||
"ac_cv_func_calloc_0_nonnull", "ac_cv_func_chown_works", "ac_cv_func_getgroups_works", "ac_cv_func_malloc_0_nonnull",
|
||||
"gl_cv_func_cbrtl_ieee", "gl_cv_func_ceil_ieee", "gl_cv_func_ceilf_ieee", "gl_cv_func_ceill_ieee",
|
||||
"gl_cv_func_chown_ctime_works", "gl_cv_func_chown_slash_works", "gl_cv_func_exp2l_ieee", "gl_cv_func_expm1_ieee",
|
||||
"gl_cv_func_fcntl_f_dupfd_works", "gl_cv_func_fdopendir_works", "gl_cv_func_floorf_ieee", "gl_cv_func_fma_works",
|
||||
"gl_cv_func_fmaf_works", "gl_cv_func_fmal_works", "gl_cv_func_fmod_ieee", "gl_cv_func_fmodf_ieee",
|
||||
"gl_cv_func_fmodl_ieee", "gl_cv_func_fpurge_works", "gl_cv_func_futimens_works", "gl_cv_func_futimesat_works",
|
||||
"gl_cv_func_getgroups_works", "gl_cv_func_gettimeofday_clobber", "gl_cv_func_hypot_ieee", "gl_cv_func_hypotf_ieee",
|
||||
"gl_cv_func_hypotl_ieee", "gl_cv_func_isfinitel_works", "gl_cv_func_isnanl_works", "gl_cv_func_link_works",
|
||||
"gl_cv_func_linkat_slash", "gl_cv_func_log10_ieee", "gl_cv_func_log10f_ieee", "gl_cv_func_log1p_ieee",
|
||||
"gl_cv_func_log1pf_ieee", "gl_cv_func_log1pl_ieee", "gl_cv_func_log2_ieee", "gl_cv_func_log2f_ieee",
|
||||
"gl_cv_func_log_ieee", "gl_cv_func_logf_ieee", "gl_cv_func_lstat_dereferences_slashed_symlink", "gl_cv_func_mbrlen_empty_input",
|
||||
"gl_cv_func_mbrtowc_empty_input", "gl_cv_func_memchr_works", "gl_cv_func_memmem_works_fast", "gl_cv_func_mkdir_trailing_dot_works",
|
||||
"gl_cv_func_mkdir_trailing_slash_works", "gl_cv_func_mkfifo_works", "gl_cv_func_mknod_works", "gl_cv_func_modf_ieee",
|
||||
"gl_cv_func_modff_ieee", "gl_cv_func_modfl_ieee", "gl_cv_func_nanosleep", "gl_cv_func_open_directory_works",
|
||||
"gl_cv_func_perror_works", "gl_cv_func_printf_directive_a", "gl_cv_func_printf_directive_f", "gl_cv_func_printf_directive_n",
|
||||
"gl_cv_func_printf_enomem", "gl_cv_func_printf_flag_zero", "gl_cv_func_printf_infinite", "gl_cv_func_printf_infinite_long_double",
|
||||
"gl_cv_func_printf_sizes_c99", "gl_cv_func_pselect_detects_ebadf", "gl_cv_func_ptsname_sets_errno", "gl_cv_func_readlink_works",
|
||||
"gl_cv_func_realpath_works", "gl_cv_func_remainder_ieee", "gl_cv_func_remainderf_ieee", "gl_cv_func_remainderl_iee",
|
||||
"gl_cv_func_rename_dest_works", "gl_cv_func_rename_link_works", "gl_cv_func_rename_slash_dst_works", "gl_cv_func_rename_slash_src_works",
|
||||
"gl_cv_func_rmdir_works", "gl_cv_func_round_ieee", "gl_cv_func_roundf_ieee", "gl_cv_func_select_detects_ebadf",
|
||||
"gl_cv_func_setenv_works", "gl_cv_func_signbit", "gl_cv_func_signbit_gcc", "gl_cv_func_sleep_works",
|
||||
"gl_cv_func_snprintf_directive_n", "gl_cv_func_snprintf_retval_c99", "gl_cv_func_snprintf_truncation_c99", "gl_cv_func_stat_dir_slash",
|
||||
"gl_cv_func_stat_file_slash", "gl_cv_func_stpncpy", "gl_cv_func_strcasestr_linear", "gl_cv_func_strchrnul_works",
|
||||
"gl_cv_func_strerror_0_works", "gl_cv_func_strstr_linear", "gl_cv_func_strtod_works", "gl_cv_func_svid_putenv",
|
||||
"gl_cv_func_symlink_works", "gl_cv_func_tdelete_works", "gl_cv_func_trunc_ieee", "gl_cv_func_truncf_ieee",
|
||||
"gl_cv_func_truncl_iee", "gl_cv_func_tzset_clobber", "gl_cv_func_ungetc_works", "gl_cv_func_unlink_honors_slashes",
|
||||
"gl_cv_func_unsetenv_works", "gl_cv_func_usleep_works", "gl_cv_func_utimensat_works", "gl_cv_func_vsnprintf_posix",
|
||||
"gl_cv_func_vsnprintf_zerosize_c99", "gl_cv_func_vsprintf_posix", "gl_cv_func_wcwidth_works", "gl_cv_func_working_getdelim",
|
||||
"gl_cv_func_working_mkstemp", "gl_cv_func_working_mktime", "gl_cv_func_working_strerror"
|
||||
];
|
||||
|
||||
for int i = 0; i < variables:len(); i += 1 {
|
||||
SystemSetEnvironmentVariable(variables[i], "yes");
|
||||
}
|
||||
}
|
||||
|
||||
// Build libraries.
|
||||
|
|
2
start.sh
2
start.sh
|
@ -69,7 +69,7 @@ if [ $? -ne 0 ]; then
|
|||
fi
|
||||
|
||||
# Compile the scripting engine.
|
||||
gcc -o bin/script util/script.c -g -Wall -Wextra -fsanitize=address
|
||||
gcc -o bin/script util/script.c -g -Wall -Wextra -O2
|
||||
|
||||
# Compile and run Build.
|
||||
gcc -o bin/build -g util/build.c -pthread -DPARALLEL_BUILD -D${ES_TARGET-TARGET_X86_64} \
|
||||
|
|
120
util/script.c
120
util/script.c
|
@ -82,6 +82,7 @@
|
|||
#define T_INDEX (91)
|
||||
#define T_LIST (92)
|
||||
#define T_IMPORT_PATH (93)
|
||||
#define T_LIST_LITERAL (94)
|
||||
|
||||
#define T_EXIT_SCOPE (100)
|
||||
#define T_END_FUNCTION (101)
|
||||
|
@ -92,6 +93,8 @@
|
|||
#define T_INTERPOLATE_BOOL (106)
|
||||
#define T_INTERPOLATE_INT (107)
|
||||
#define T_INTERPOLATE_FLOAT (108)
|
||||
#define T_DUP (109)
|
||||
#define T_SWAP (110)
|
||||
|
||||
#define T_FLOAT_ADD (120)
|
||||
#define T_FLOAT_MINUS (121)
|
||||
|
@ -837,9 +840,39 @@ Node *ParseExpression(Tokenizer *tokenizer, bool allowAssignment, uint8_t preced
|
|||
node->firstChild = ParseType(tokenizer, false, false);
|
||||
node->expressionType = node->firstChild;
|
||||
if (!node->firstChild) return NULL;
|
||||
} else if (node->token.type == T_LEFT_SQUARE) {
|
||||
node->type = T_LIST_LITERAL;
|
||||
Node **link = &node->firstChild;
|
||||
bool needComma = false;
|
||||
|
||||
while (true) {
|
||||
Token peek = TokenPeek(tokenizer);
|
||||
|
||||
if (peek.type == T_ERROR) {
|
||||
return NULL;
|
||||
} else if (peek.type == T_RIGHT_SQUARE) {
|
||||
TokenNext(tokenizer);
|
||||
break;
|
||||
}
|
||||
|
||||
if (needComma) {
|
||||
if (peek.type != T_COMMA) {
|
||||
PrintError(tokenizer, "Expected a comma between list literal items.\n");
|
||||
return NULL;
|
||||
} else {
|
||||
TokenNext(tokenizer);
|
||||
}
|
||||
}
|
||||
|
||||
Node *item = ParseExpression(tokenizer, false, 0);
|
||||
if (!item) return NULL;
|
||||
*link = item;
|
||||
link = &item->sibling;
|
||||
needComma = true;
|
||||
}
|
||||
} else {
|
||||
PrintError2(tokenizer, node, "Expected an expression. "
|
||||
"Expressions can start with a variable identifier, a string literal, a number, 'len', 'new', '!' or '('.\n");
|
||||
"Expressions can start with a variable identifier, a string literal, a number, 'len', 'new', '!', '[' or '('.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2098,6 +2131,26 @@ bool ASTSetTypes(Tokenizer *tokenizer, Node *node) {
|
|||
}
|
||||
|
||||
node->expressionType = &globalExpressionTypeBool;
|
||||
} else if (node->type == T_LIST_LITERAL) {
|
||||
if (!node->firstChild) {
|
||||
// TODO Support empty list literals?
|
||||
PrintError2(tokenizer, node, "Empty list literals are not allowed. Instead, put 'new T[]' where 'T' is the item type.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
Node *item = node->firstChild;
|
||||
node->expressionType = (Node *) AllocateFixed(sizeof(Node));
|
||||
node->expressionType->type = T_LIST;
|
||||
node->expressionType->firstChild = item->expressionType;
|
||||
|
||||
while (item) {
|
||||
if (!ASTMatching(node->expressionType->firstChild, item->expressionType)) {
|
||||
PrintError2(tokenizer, item, "The type of this item is different to the ones before it in the list.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
item = item->sibling;
|
||||
}
|
||||
} else {
|
||||
PrintDebug("ASTSetTypes %d\n", node->type);
|
||||
Assert(false);
|
||||
|
@ -2454,6 +2507,49 @@ bool FunctionBuilderRecurse(Tokenizer *tokenizer, Node *node, FunctionBuilder *b
|
|||
|
||||
FunctionBuilderAddLineNumber(builder, node);
|
||||
FunctionBuilderAppend(builder, &node->operationType, sizeof(node->operationType));
|
||||
return true;
|
||||
} else if (node->type == T_LIST_LITERAL) {
|
||||
// Step 1: Create the list.
|
||||
uint8_t b = T_NEW;
|
||||
int16_t isManaged = ASTIsManagedType(node->expressionType->firstChild) ? -2 : -1;
|
||||
FunctionBuilderAddLineNumber(builder, node);
|
||||
FunctionBuilderAppend(builder, &b, sizeof(b));
|
||||
FunctionBuilderAppend(builder, &isManaged, sizeof(isManaged));
|
||||
|
||||
// Step 2: Resize the list.
|
||||
uint32_t size = 0;
|
||||
Node *item = node->firstChild;
|
||||
while (item) { size++; item = item->sibling; }
|
||||
b = T_DUP;
|
||||
FunctionBuilderAppend(builder, &b, sizeof(b));
|
||||
b = T_NUMERIC_LITERAL;
|
||||
FunctionBuilderAppend(builder, &b, sizeof(b));
|
||||
Value v;
|
||||
v.i = size;
|
||||
FunctionBuilderAppend(builder, &v, sizeof(v));
|
||||
b = T_OP_RESIZE;
|
||||
FunctionBuilderAppend(builder, &b, sizeof(b));
|
||||
|
||||
// Step 3: Populate the list.
|
||||
item = node->firstChild;
|
||||
uint32_t i = 0;
|
||||
|
||||
while (item) {
|
||||
b = T_DUP;
|
||||
FunctionBuilderAppend(builder, &b, sizeof(b));
|
||||
FunctionBuilderRecurse(tokenizer, item, builder, false);
|
||||
b = T_SWAP;
|
||||
FunctionBuilderAppend(builder, &b, sizeof(b));
|
||||
b = T_NUMERIC_LITERAL;
|
||||
FunctionBuilderAppend(builder, &b, sizeof(b));
|
||||
Value v;
|
||||
v.i = i++;
|
||||
FunctionBuilderAppend(builder, &v, sizeof(v));
|
||||
b = T_EQUALS_LIST;
|
||||
FunctionBuilderAppend(builder, &b, sizeof(b));
|
||||
item = item->sibling;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2825,6 +2921,7 @@ int ScriptExecuteFunction(uintptr_t instructionPointer, ExecutionContext *contex
|
|||
|
||||
while (true) {
|
||||
uint8_t command = functionData[instructionPointer++];
|
||||
// PrintDebug("--> %d\n", command);
|
||||
|
||||
if (command == T_BLOCK || command == T_FUNCBODY) {
|
||||
uint16_t newVariableCount = functionData[instructionPointer + 0] + (functionData[instructionPointer + 1] << 8);
|
||||
|
@ -3359,6 +3456,27 @@ int ScriptExecuteFunction(uintptr_t instructionPointer, ExecutionContext *contex
|
|||
} else if (command == T_POP) {
|
||||
if (context->stackPointer < 1) return -1;
|
||||
context->stackPointer--;
|
||||
} else if (command == T_DUP) {
|
||||
if (context->stackPointer < 1) return -1;
|
||||
|
||||
if (context->stackPointer == context->stackEntriesAllocated) {
|
||||
PrintError4(context, instructionPointer - 1, "Stack overflow.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
context->stack[context->stackPointer] = context->stack[context->stackPointer - 1];
|
||||
context->stackIsManaged[context->stackPointer] = context->stackIsManaged[context->stackPointer - 1];
|
||||
context->stackPointer++;
|
||||
} else if (command == T_SWAP) {
|
||||
if (context->stackPointer < 2) return -1;
|
||||
Value v1 = context->stack[context->stackPointer - 1];
|
||||
Value v2 = context->stack[context->stackPointer - 2];
|
||||
bool m1 = context->stackIsManaged[context->stackPointer - 1];
|
||||
bool m2 = context->stackIsManaged[context->stackPointer - 2];
|
||||
context->stack[context->stackPointer - 1] = v2;
|
||||
context->stack[context->stackPointer - 2] = v1;
|
||||
context->stackIsManaged[context->stackPointer - 1] = m2;
|
||||
context->stackIsManaged[context->stackPointer - 2] = m1;
|
||||
} else if (command == T_ASSERT) {
|
||||
if (context->stackPointer < 1) return -1;
|
||||
Value condition = context->stack[--context->stackPointer];
|
||||
|
|
Loading…
Reference in New Issue