mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Prefix '++' working (postfix is next)
This commit is contained in:
3
.notes/misc.txt
Normal file
3
.notes/misc.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
type coercion
|
||||
permanent strings?
|
||||
concat & free? (strings)
|
||||
@@ -1,64 +1,13 @@
|
||||
//logical short-circuits and chained assignments
|
||||
|
||||
//logical AND
|
||||
|
||||
//increment & decrement (prefix)
|
||||
{
|
||||
var a = 1;
|
||||
var b = 2;
|
||||
var c = a + 1 && b + 2;
|
||||
var a = 42;
|
||||
assert a == 42;
|
||||
assert ++a == 43;
|
||||
assert a == 43;
|
||||
assert --a == 42;
|
||||
assert a == 42;
|
||||
|
||||
assert a == 1, "short circuit 1.1";
|
||||
assert b == 2, "short circuit 1.2";
|
||||
assert c == 4, "short circuit 1.3";
|
||||
}
|
||||
|
||||
{
|
||||
var a = 1;
|
||||
var b = 2;
|
||||
var c = a = (a + 1) && b + 2;
|
||||
|
||||
assert a == 4, "short circuit 2.1";
|
||||
assert b == 2, "short circuit 2.2";
|
||||
assert c == 4, "short circuit 2.3";
|
||||
}
|
||||
|
||||
{
|
||||
var a = 1;
|
||||
var b = 2;
|
||||
var c = a = a + 1 && b + 2;
|
||||
|
||||
assert a == 4, "short circuit 3.1";
|
||||
assert b == 2, "short circuit 3.2";
|
||||
assert c == 4, "short circuit 3.3";
|
||||
}
|
||||
|
||||
|
||||
//logical OR
|
||||
{
|
||||
var a = 1;
|
||||
var b = 2;
|
||||
var c = a + 1 || b + 2;
|
||||
|
||||
assert a == 1, "short circuit 4.1";
|
||||
assert b == 2, "short circuit 4.2";
|
||||
assert c == 2, "short circuit 4.3";
|
||||
}
|
||||
|
||||
{
|
||||
var a = 1;
|
||||
var b = 2;
|
||||
var c = a = (a + 1) || b + 2;
|
||||
|
||||
assert a == 2, "short circuit 5.1";
|
||||
assert b == 2, "short circuit 5.2";
|
||||
assert c == 2, "short circuit 5.3";
|
||||
}
|
||||
|
||||
{
|
||||
var a = 1;
|
||||
var b = 2;
|
||||
var c = a = a + 1 || b + 2;
|
||||
|
||||
assert a == 2, "short circuit 6.1";
|
||||
assert b == 2, "short circuit 6.2";
|
||||
assert c == 2, "short circuit 6.3";
|
||||
print a;
|
||||
}
|
||||
@@ -72,8 +72,8 @@ typedef enum Toy_AstFlag {
|
||||
|
||||
//unary flags
|
||||
TOY_AST_FLAG_NEGATE = 43,
|
||||
TOY_AST_FLAG_INCREMENT = 44,
|
||||
TOY_AST_FLAG_DECREMENT = 45,
|
||||
TOY_AST_FLAG_PREFIX_INCREMENT = 44,
|
||||
TOY_AST_FLAG_PREFIX_DECREMENT = 45,
|
||||
|
||||
// TOY_AST_FLAG_TERNARY,
|
||||
} Toy_AstFlag;
|
||||
|
||||
@@ -180,8 +180,8 @@ static ParsingTuple parsingRulesetTable[] = {
|
||||
{PREC_ASSIGNMENT,NULL,binary},// TOY_TOKEN_OPERATOR_MULTIPLY_ASSIGN,
|
||||
{PREC_ASSIGNMENT,NULL,binary},// TOY_TOKEN_OPERATOR_DIVIDE_ASSIGN,
|
||||
{PREC_ASSIGNMENT,NULL,binary},// TOY_TOKEN_OPERATOR_MODULO_ASSIGN,
|
||||
{PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_INCREMENT,
|
||||
{PREC_NONE,NULL,NULL},// TOY_TOKEN_OPERATOR_DECREMENT,
|
||||
{PREC_CALL,unary,NULL},// TOY_TOKEN_OPERATOR_INCREMENT,
|
||||
{PREC_CALL,unary,NULL},// TOY_TOKEN_OPERATOR_DECREMENT,
|
||||
{PREC_ASSIGNMENT,NULL,binary},// TOY_TOKEN_OPERATOR_ASSIGN,
|
||||
|
||||
//comparator operators
|
||||
@@ -419,6 +419,26 @@ static Toy_AstFlag unary(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast*
|
||||
Toy_private_emitAstUnary(bucketHandle, rootHandle, TOY_AST_FLAG_NEGATE);
|
||||
}
|
||||
|
||||
else if (parser->previous.type == TOY_TOKEN_OPERATOR_INCREMENT || parser->previous.type == TOY_TOKEN_OPERATOR_DECREMENT) {
|
||||
Toy_AstFlag flag = parser->previous.type == TOY_TOKEN_OPERATOR_INCREMENT ? TOY_AST_FLAG_PREFIX_INCREMENT : TOY_AST_FLAG_PREFIX_DECREMENT;
|
||||
|
||||
//grab the info below
|
||||
Toy_Ast* primary = NULL;
|
||||
|
||||
parsePrecedence(bucketHandle, parser, &primary, PREC_PRIMARY);
|
||||
|
||||
//double check it's a name string within an access NOTE: doing some fiddling with the existing AST here
|
||||
if (primary->type != TOY_AST_VAR_ACCESS || primary->varAccess.child->type != TOY_AST_VALUE || TOY_VALUE_IS_STRING(primary->varAccess.child->value.value) != true || TOY_VALUE_AS_STRING(primary->varAccess.child->value.value)->info.type != TOY_STRING_NAME) {
|
||||
printError(parser, parser->previous, "Unexpected non-name-string token in unary operator increment precedence rule");
|
||||
Toy_private_emitAstError(bucketHandle, rootHandle);
|
||||
}
|
||||
else {
|
||||
//swap the varAccess for a unary prefix, as the latter leaves the value on the stack
|
||||
*rootHandle = primary->varAccess.child;
|
||||
Toy_private_emitAstUnary(bucketHandle, rootHandle, flag);
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
printError(parser, parser->previous, "Unexpected token passed to unary precedence rule");
|
||||
Toy_private_emitAstError(bucketHandle, rootHandle);
|
||||
|
||||
@@ -176,10 +176,11 @@ static unsigned int writeInstructionValue(Toy_Routine** rt, Toy_AstValue ast) {
|
||||
}
|
||||
|
||||
static unsigned int writeInstructionUnary(Toy_Routine** rt, Toy_AstUnary ast) {
|
||||
//working with a stack means the child gets placed first
|
||||
unsigned int result = writeRoutineCode(rt, ast.child);
|
||||
unsigned int result = 0;
|
||||
|
||||
if (ast.flag == TOY_AST_FLAG_NEGATE) {
|
||||
result = writeRoutineCode(rt, ast.child);
|
||||
|
||||
EMIT_BYTE(rt, code, TOY_OPCODE_NEGATE);
|
||||
|
||||
//4-byte alignment
|
||||
@@ -187,6 +188,42 @@ static unsigned int writeInstructionUnary(Toy_Routine** rt, Toy_AstUnary ast) {
|
||||
EMIT_BYTE(rt, code, 0);
|
||||
EMIT_BYTE(rt, code, 0);
|
||||
}
|
||||
|
||||
else if (ast.flag == TOY_AST_FLAG_PREFIX_INCREMENT || ast.flag == TOY_AST_FLAG_PREFIX_DECREMENT) { //NOTE: tightly coupled to the parser's logic, and somewhat duplicates ACCESS
|
||||
//read the var name onto the stack
|
||||
Toy_String* name = TOY_VALUE_AS_STRING(ast.child->value.value);
|
||||
|
||||
EMIT_BYTE(rt, code, TOY_OPCODE_READ);
|
||||
EMIT_BYTE(rt, code, TOY_VALUE_STRING);
|
||||
EMIT_BYTE(rt, code, TOY_STRING_NAME);
|
||||
EMIT_BYTE(rt, code, name->info.length); //store the length (max 255)
|
||||
|
||||
emitString(rt, name);
|
||||
|
||||
//duplicate the var name, then get the value
|
||||
EMIT_BYTE(rt, code,TOY_OPCODE_DUPLICATE);
|
||||
EMIT_BYTE(rt, code, TOY_OPCODE_ACCESS); //squeezed
|
||||
EMIT_BYTE(rt, code, 0);
|
||||
EMIT_BYTE(rt, code, 0);
|
||||
|
||||
//read the integer '1'
|
||||
EMIT_BYTE(rt, code, TOY_OPCODE_READ);
|
||||
EMIT_BYTE(rt, code, TOY_VALUE_INTEGER);
|
||||
EMIT_BYTE(rt, code, 0);
|
||||
EMIT_BYTE(rt, code, 0);
|
||||
|
||||
EMIT_INT(rt, code, 1);
|
||||
|
||||
//add (or subtract) the two values, then assign (pops the second duplicate, and leaves value on the stack)
|
||||
EMIT_BYTE(rt, code, ast.flag == TOY_AST_FLAG_PREFIX_INCREMENT ? TOY_OPCODE_ADD : TOY_OPCODE_SUBTRACT);
|
||||
EMIT_BYTE(rt, code,TOY_OPCODE_ASSIGN); //squeezed
|
||||
EMIT_BYTE(rt, code,0);
|
||||
EMIT_BYTE(rt, code,0);
|
||||
|
||||
//leaves one value on the stack
|
||||
result = 1;
|
||||
}
|
||||
|
||||
else {
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Invalid AST unary flag found\n" TOY_CC_RESET);
|
||||
exit(-1);
|
||||
|
||||
@@ -307,7 +307,7 @@ static void processAccess(Toy_VM* vm) {
|
||||
Toy_Value name = Toy_popStack(&vm->stack);
|
||||
|
||||
//check name string type
|
||||
if (!TOY_VALUE_IS_STRING(name) && TOY_VALUE_AS_STRING(name)->info.type != TOY_STRING_NAME) {
|
||||
if (!TOY_VALUE_IS_STRING(name) || TOY_VALUE_AS_STRING(name)->info.type != TOY_STRING_NAME) {
|
||||
Toy_pushStack(&vm->stack, TOY_VALUE_FROM_NULL());
|
||||
Toy_error("Invalid access target");
|
||||
return;
|
||||
|
||||
@@ -112,23 +112,37 @@ print !false; //true
|
||||
}
|
||||
|
||||
//types
|
||||
var a: int;
|
||||
var b: int = 42;
|
||||
{
|
||||
var a: int;
|
||||
var b: int = 42;
|
||||
|
||||
a = 69;
|
||||
b = 8891;
|
||||
a = 69;
|
||||
b = 8891;
|
||||
|
||||
print a;
|
||||
print b;
|
||||
print a;
|
||||
print b;
|
||||
}
|
||||
|
||||
//constants
|
||||
var c: int const = 42;
|
||||
|
||||
print c;
|
||||
{
|
||||
var c: int const = 42;
|
||||
print c;
|
||||
}
|
||||
|
||||
//indexing
|
||||
var s = "Hello" .. "world!";
|
||||
{
|
||||
var s = "Hello" .. "world!";
|
||||
print s[3, 3];
|
||||
}
|
||||
|
||||
print s[3, 3];
|
||||
//increment & decrement (prefix)
|
||||
{
|
||||
var a = 42;
|
||||
assert a == 42, "prefix increment & decrement 1.1";
|
||||
assert ++a == 43, "prefix increment & decrement 1.2";
|
||||
assert a == 43, "prefix increment & decrement 1.3";
|
||||
assert --a == 42, "prefix increment & decrement 1.4";
|
||||
assert a == 42, "prefix increment & decrement 1.5";
|
||||
}
|
||||
|
||||
//TODO: type casting
|
||||
|
||||
Reference in New Issue
Block a user