scripting engine add unary negate; add EsTextboxAppend; fix port script issue

This commit is contained in:
nakst 2022-02-05 08:50:31 +00:00
parent 6d0810cb66
commit 129d072a49
7 changed files with 99 additions and 74 deletions

View File

@ -3123,10 +3123,10 @@ bool /* returns false on fatal error */ DesktopSyscall(EsObjectID windowID, Appl
}
void EmbeddedWindowDestroyed(EsObjectID id) {
EsMenuCloseAll(); // The tab will be destroyed, but menus might be keeping pointers to it.
ApplicationInstance *instance = ApplicationInstanceFindByWindowID(id, true /* remove if found */);
if (!instance) return;
EsMenuCloseAll(); // The tab will be destroyed, but menus might be keeping pointers to it.
EsHandleClose(instance->embeddedWindowHandle);
ApplicationInstanceCleanup(instance);

View File

@ -2499,6 +2499,7 @@ function EsElement *EsButtonGetCheckBuddy(EsButton *button); // TODO Public pro
function EsTextbox *EsTextboxCreate(EsElement *parent, uint64_t flags = ES_FLAGS_DEFAULT, const EsStyle *style = ES_NULL);
function bool EsTextboxFind(EsTextbox *textbox, STRING string, int32_t *line, int32_t *byte, uint32_t flags);
function void EsTextboxInsert(EsTextbox *textbox, STRING string = BLANK_STRING, bool sendUpdatedMessage = true); // Deletes existing selection first.
function void EsTextboxAppend(EsTextbox *textbox, STRING string = BLANK_STRING, bool sendUpdatedMessage = true); // Ignores the user's selection.
function char *EsTextboxGetContents(EsTextbox *textbox, size_t *bytes = ES_NULL, uint32_t flags = ES_FLAGS_DEFAULT); // Result will be zero-terminated; free with EsHeapFree.
function double EsTextboxGetContentsAsDouble(EsTextbox *textbox, uint32_t flags = ES_FLAGS_DEFAULT);
function size_t EsTextboxGetLineLength(EsTextbox *textbox, uintptr_t line = 0);

View File

@ -1196,6 +1196,15 @@ void EsTextboxInsert(EsTextbox *textbox, const char *string, ptrdiff_t stringByt
&& textbox->carets[1].byte >= 0 && textbox->carets[1].byte <= textbox->lines[textbox->carets[1].line].lengthBytes);
}
void EsTextboxAppend(EsTextbox *textbox, const char *string, ptrdiff_t stringBytes, bool sendUpdatedMessage) {
TextboxCaret oldCarets[2];
oldCarets[0] = textbox->carets[0];
oldCarets[1] = textbox->carets[1];
EsTextboxMoveCaretRelative(textbox, ES_TEXTBOX_MOVE_CARET_ALL);
EsTextboxInsert(textbox, string, stringBytes, sendUpdatedMessage);
EsTextboxSetSelection(textbox, oldCarets[0].line, oldCarets[0].byte, oldCarets[1].line, oldCarets[1].byte);
}
char *EsTextboxGetContents(EsTextbox *textbox, size_t *_bytes, uint32_t flags) {
EsMessageMutexCheck();

View File

@ -232,20 +232,20 @@ void PortGCC() {
if !resumeBuild {
if buildCross {
assert PathDeleteRecursively("cross");
PathDeleteRecursively("cross");
}
// Cleanup.
assert PathDeleteRecursively("bin/build-binutils");
assert PathDeleteRecursively("bin/build-gcc");
assert PathDeleteRecursively("bin/build-mpfr");
assert PathDeleteRecursively("bin/build-mpc");
assert PathDeleteRecursively("bin/build-gmp");
assert PathDeleteRecursively("bin/binutils-src");
assert PathDeleteRecursively("bin/gcc-src");
assert PathDeleteRecursively("bin/mpfr-src");
assert PathDeleteRecursively("bin/mpc-src");
assert PathDeleteRecursively("bin/gmp-src");
PathDeleteRecursively("bin/build-binutils");
PathDeleteRecursively("bin/build-gcc");
PathDeleteRecursively("bin/build-mpfr");
PathDeleteRecursively("bin/build-mpc");
PathDeleteRecursively("bin/build-gmp");
PathDeleteRecursively("bin/binutils-src");
PathDeleteRecursively("bin/gcc-src");
PathDeleteRecursively("bin/mpfr-src");
PathDeleteRecursively("bin/mpc-src");
PathDeleteRecursively("bin/gmp-src");
// Create folders.
assert PathCreateDirectory("bin/build-binutils");
@ -409,16 +409,16 @@ void PortGCC() {
// Cleanup.
runningMakefiles = false;
assert PathDeleteRecursively("bin/build-binutils");
assert PathDeleteRecursively("bin/build-gcc");
assert PathDeleteRecursively("bin/build-mpc");
assert PathDeleteRecursively("bin/build-mpfr");
assert PathDeleteRecursively("bin/build-gmp");
assert PathDeleteRecursively("bin/binutils-src");
assert PathDeleteRecursively("bin/gcc-src");
assert PathDeleteRecursively("bin/mpc-src");
assert PathDeleteRecursively("bin/mpfr-src");
assert PathDeleteRecursively("bin/gmp-src");
PathDeleteRecursively("bin/build-binutils");
PathDeleteRecursively("bin/build-gcc");
PathDeleteRecursively("bin/build-mpc");
PathDeleteRecursively("bin/build-mpfr");
PathDeleteRecursively("bin/build-gmp");
PathDeleteRecursively("bin/binutils-src");
PathDeleteRecursively("bin/gcc-src");
PathDeleteRecursively("bin/mpc-src");
PathDeleteRecursively("bin/mpfr-src");
PathDeleteRecursively("bin/gmp-src");
PrintStdErrHighlight("Build succeeded.\n");
}

View File

@ -165,6 +165,7 @@ EsMountPointAdd=163
EsSystemConfigurationReadFileTypes=164
EsImageLoad=165
EsMountPointRemove=166
EsTextboxAppend=167
EsCRTabs=168
EsCRTacosf=169
EsCRTasinf=170

View File

@ -1976,13 +1976,11 @@ void _start() {
EsCommandSetEnabled(&commandBuild, true);
EsCommandSetEnabled(&commandLaunch, true);
EsTextboxMoveCaretRelative(textboxLog, ES_TEXTBOX_MOVE_CARET_ALL);
if (message->type == MSG_BUILD_FAILED) {
EsTextboxInsert(textboxLog, INTERFACE_STRING(BuildCoreBuildFailed), false);
EsTextboxAppend(textboxLog, INTERFACE_STRING(BuildCoreBuildFailed), false);
EsElementFocus(buttonBuild, ES_ELEMENT_FOCUS_ONLY_IF_NO_FOCUSED_ELEMENT);
} else {
EsTextboxInsert(textboxLog, INTERFACE_STRING(BuildCoreBuildSuccess), false);
EsTextboxAppend(textboxLog, INTERFACE_STRING(BuildCoreBuildSuccess), false);
EsElementFocus(buttonLaunch, ES_ELEMENT_FOCUS_ONLY_IF_NO_FOCUSED_ELEMENT);
}
@ -1990,9 +1988,7 @@ void _start() {
_EsPathAnnouncePathMoved(NULL, 0, workingDirectory, workingDirectoryBytes);
} else if (message->type == MSG_LOG) {
char *copy = message->user.context1.p;
EsTextboxMoveCaretRelative(textboxLog, ES_TEXTBOX_MOVE_CARET_ALL);
EsTextboxInsert(textboxLog, copy, -1, false);
EsTextboxEnsureCaretVisible(textboxLog, false);
EsTextboxAppend(textboxLog, copy, -1, false);
EsHeapFree(copy, 0, NULL);
}
}

View File

@ -2,9 +2,9 @@
// - Other list operations: insert_many, delete, delete_many, delete_last.
// - Maps: T[int], T[str].
// - Control flow: break, continue.
// - Other operators: remainder, bitwise shifts, unary minus, bitwise AND/OR/XOR/NOT, ternary.
// - Other operators: remainder, bitwise shifts, bitwise AND/OR/XOR/NOT, ternary.
// - Enums, bitsets.
// - Resolving type identifiers when structs or function pointers contain references to other structs or function pointers.
// - Named optional arguments with default values.
// TODO Larger missing features:
// - Serialization.
@ -44,30 +44,31 @@
#define T_MINUS (41)
#define T_ASTERISK (42)
#define T_SLASH (43)
#define T_LEFT_ROUND (44)
#define T_RIGHT_ROUND (45)
#define T_LEFT_SQUARE (46)
#define T_RIGHT_SQUARE (47)
#define T_LEFT_FANCY (48)
#define T_RIGHT_FANCY (49)
#define T_COMMA (50)
#define T_EQUALS (51)
#define T_SEMICOLON (52)
#define T_GREATER_THAN (53)
#define T_LESS_THAN (54)
#define T_GT_OR_EQUAL (55)
#define T_LT_OR_EQUAL (56)
#define T_DOUBLE_EQUALS (57)
#define T_NOT_EQUALS (58)
#define T_LOGICAL_AND (59)
#define T_LOGICAL_OR (60)
#define T_ADD_EQUALS (61)
#define T_MINUS_EQUALS (62)
#define T_ASTERISK_EQUALS (63)
#define T_SLASH_EQUALS (64)
#define T_DOT (65)
#define T_COLON (66)
#define T_LOGICAL_NOT (67)
#define T_NEGATE (44)
#define T_LEFT_ROUND (45)
#define T_RIGHT_ROUND (46)
#define T_LEFT_SQUARE (47)
#define T_RIGHT_SQUARE (48)
#define T_LEFT_FANCY (49)
#define T_RIGHT_FANCY (50)
#define T_COMMA (51)
#define T_EQUALS (52)
#define T_SEMICOLON (53)
#define T_GREATER_THAN (54)
#define T_LESS_THAN (55)
#define T_GT_OR_EQUAL (56)
#define T_LT_OR_EQUAL (57)
#define T_DOUBLE_EQUALS (58)
#define T_NOT_EQUALS (59)
#define T_LOGICAL_AND (60)
#define T_LOGICAL_OR (61)
#define T_ADD_EQUALS (62)
#define T_MINUS_EQUALS (63)
#define T_ASTERISK_EQUALS (64)
#define T_SLASH_EQUALS (65)
#define T_DOT (66)
#define T_COLON (67)
#define T_LOGICAL_NOT (68)
#define T_ROOT (80)
#define T_FUNCBODY (81)
@ -102,17 +103,18 @@
#define T_FLOAT_MINUS (121)
#define T_FLOAT_ASTERISK (122)
#define T_FLOAT_SLASH (123)
#define T_FLOAT_GREATER_THAN (124)
#define T_FLOAT_LESS_THAN (125)
#define T_FLOAT_GT_OR_EQUAL (126)
#define T_FLOAT_LT_OR_EQUAL (127)
#define T_FLOAT_DOUBLE_EQUALS (128)
#define T_FLOAT_NOT_EQUALS (129)
#define T_STR_DOUBLE_EQUALS (130)
#define T_STR_NOT_EQUALS (131)
#define T_EQUALS_DOT (132)
#define T_EQUALS_LIST (133)
#define T_INDEX_LIST (134)
#define T_FLOAT_NEGATE (124)
#define T_FLOAT_GREATER_THAN (125)
#define T_FLOAT_LESS_THAN (126)
#define T_FLOAT_GT_OR_EQUAL (127)
#define T_FLOAT_LT_OR_EQUAL (128)
#define T_FLOAT_DOUBLE_EQUALS (129)
#define T_FLOAT_NOT_EQUALS (130)
#define T_STR_DOUBLE_EQUALS (131)
#define T_STR_NOT_EQUALS (132)
#define T_EQUALS_DOT (133)
#define T_EQUALS_LIST (134)
#define T_INDEX_LIST (135)
#define T_OP_RESIZE (140)
#define T_OP_ADD (141)
@ -664,6 +666,7 @@ uint8_t TokenLookupPrecedence(uint8_t t) {
if (t == T_ASTERISK) return 60;
if (t == T_SLASH) return 60;
if (t == T_LOGICAL_NOT) return 70;
if (t == T_NEGATE) return 70;
if (t == T_DOT) return 80;
if (t == T_COLON) return 80;
if (t == T_AWAIT) return 90;
@ -1032,9 +1035,9 @@ Node *ParseExpression(Tokenizer *tokenizer, bool allowAssignment, uint8_t preced
} else if (node->token.type == T_NUMERIC_LITERAL
|| node->token.type == T_TRUE || node->token.type == T_FALSE || node->token.type == T_NULL) {
node->type = node->token.type;
} else if (node->token.type == T_LOGICAL_NOT) {
node->type = node->token.type;
node->firstChild = ParseExpression(tokenizer, false, TokenLookupPrecedence(node->token.type));
} else if (node->token.type == T_LOGICAL_NOT || node->token.type == T_MINUS) {
node->type = node->token.type == T_MINUS ? T_NEGATE : T_LOGICAL_NOT;
node->firstChild = ParseExpression(tokenizer, false, TokenLookupPrecedence(node->type));
} else if (node->token.type == T_LEFT_ROUND) {
node = ParseExpression(tokenizer, false, 0);
if (!node) return NULL;
@ -1086,7 +1089,7 @@ Node *ParseExpression(Tokenizer *tokenizer, bool allowAssignment, uint8_t preced
node->firstChild = ParseExpression(tokenizer, false, TokenLookupPrecedence(node->token.type));
} 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, 'await', 'new', '-', '!', '[' or '('.\n");
return NULL;
}
@ -1846,7 +1849,7 @@ bool ASTSetScopes(Tokenizer *tokenizer, ExecutionContext *context, Node *node, S
}
}
if (node->type != T_STRUCT) {
{
child = node->firstChild;
while (child) {
@ -2143,8 +2146,9 @@ bool ASTSetTypes(Tokenizer *tokenizer, Node *node) {
&& !ASTMatching(node->firstChild->expressionType, &globalExpressionTypeFloat)
&& !ASTMatching(node->firstChild->expressionType, &globalExpressionTypeStr)
&& !ASTMatching(node->firstChild->expressionType, &globalExpressionTypeBool)
&& (!node->firstChild->expressionType || node->firstChild->expressionType->type != T_LIST)) {
PrintError2(tokenizer, node, "This operator expects either integers, floats, strings or booleans.\n");
&& (!node->firstChild->expressionType || node->firstChild->expressionType->type != T_LIST)
&& (!node->firstChild->expressionType || node->firstChild->expressionType->type != T_STRUCT)) {
PrintError2(tokenizer, node, "These types cannot be compared.\n");
return false;
}
} else {
@ -2439,6 +2443,14 @@ bool ASTSetTypes(Tokenizer *tokenizer, Node *node) {
}
node->expressionType = &globalExpressionTypeBool;
} else if (node->type == T_NEGATE) {
if (!ASTMatching(node->firstChild->expressionType, &globalExpressionTypeInt)
&& !ASTMatching(node->firstChild->expressionType, &globalExpressionTypeFloat)) {
PrintError2(tokenizer, node, "Expected a int or float for the unary negate '-' operator.\n");
return false;
}
node->expressionType = node->firstChild->expressionType;
} else if (node->type == T_LIST_LITERAL) {
if (!node->firstChild) {
// TODO Support empty list literals?
@ -2908,7 +2920,7 @@ bool FunctionBuilderRecurse(Tokenizer *tokenizer, Node *node, FunctionBuilder *b
} else if (node->type == T_ASSERT || node->type == T_NULL || node->type == T_LOGICAL_NOT || node->type == T_AWAIT) {
FunctionBuilderAddLineNumber(builder, node);
FunctionBuilderAppend(builder, &node->type, sizeof(node->type));
} else if (node->type == T_ADD || node->type == T_MINUS || node->type == T_ASTERISK || node->type == T_SLASH) {
} else if (node->type == T_ADD || node->type == T_MINUS || node->type == T_ASTERISK || node->type == T_SLASH || node->type == T_NEGATE) {
uint8_t b = node->expressionType->type == T_FLOAT ? node->type - T_ADD + T_FLOAT_ADD
: node->expressionType->type == T_STR ? T_CONCAT : node->type;
FunctionBuilderAddLineNumber(builder, node);
@ -3710,6 +3722,9 @@ int ScriptExecuteFunction(uintptr_t instructionPointer, ExecutionContext *contex
context->c->stack[context->c->stackPointer - 2].i = context->c->stack[context->c->stackPointer - 2].f / context->c->stack[context->c->stackPointer - 1].f;
context->c->stackPointer--;
} else if (command == T_NEGATE) {
if (context->c->stackPointer < 1) return -1;
context->c->stack[context->c->stackPointer - 1].i = -context->c->stack[context->c->stackPointer - 1].i;
} else if (command == T_FLOAT_ADD) {
if (context->c->stackPointer < 2) return -1;
context->c->stack[context->c->stackPointer - 2].f = context->c->stack[context->c->stackPointer - 2].f + context->c->stack[context->c->stackPointer - 1].f;
@ -3726,6 +3741,9 @@ int ScriptExecuteFunction(uintptr_t instructionPointer, ExecutionContext *contex
if (context->c->stackPointer < 2) return -1;
context->c->stack[context->c->stackPointer - 2].f = context->c->stack[context->c->stackPointer - 2].f / context->c->stack[context->c->stackPointer - 1].f;
context->c->stackPointer--;
} else if (command == T_FLOAT_NEGATE) {
if (context->c->stackPointer < 1) return -1;
context->c->stack[context->c->stackPointer - 1].f = -context->c->stack[context->c->stackPointer - 1].f;
} else if (command == T_LESS_THAN) {
if (context->c->stackPointer < 2) return -1;
context->c->stack[context->c->stackPointer - 2].i = context->c->stack[context->c->stackPointer - 2].i < context->c->stack[context->c->stackPointer - 1].i;