mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Implemented _concat
This commit is contained in:
@@ -5,6 +5,115 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static int nativeConcat(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||||
|
//no arguments
|
||||||
|
if (arguments->count != 2) {
|
||||||
|
interpreter->errorOutput("Incorrect number of arguments to _concat\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the args
|
||||||
|
Toy_Literal otherLiteral = Toy_popLiteralArray(arguments);
|
||||||
|
Toy_Literal selfLiteral = Toy_popLiteralArray(arguments);
|
||||||
|
|
||||||
|
//parse to value if needed
|
||||||
|
Toy_Literal selfLiteralIdn = selfLiteral;
|
||||||
|
if (TOY_IS_IDENTIFIER(selfLiteral) && Toy_parseIdentifierToValue(interpreter, &selfLiteral)) {
|
||||||
|
Toy_freeLiteral(selfLiteralIdn);
|
||||||
|
}
|
||||||
|
|
||||||
|
Toy_Literal otherLiteralIdn = otherLiteral;
|
||||||
|
if (TOY_IS_IDENTIFIER(otherLiteral) && Toy_parseIdentifierToValue(interpreter, &otherLiteral)) {
|
||||||
|
Toy_freeLiteral(otherLiteralIdn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//for each self type
|
||||||
|
if (TOY_IS_ARRAY(selfLiteral)) {
|
||||||
|
if (!TOY_IS_ARRAY(otherLiteral)) {
|
||||||
|
interpreter->errorOutput("Incorrect argument type passed to _concat (unknown type for other)\n");
|
||||||
|
Toy_freeLiteral(selfLiteral);
|
||||||
|
Toy_freeLiteral(otherLiteral);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//append each element of other to self, one-by-one
|
||||||
|
for (int i = 0; i < TOY_AS_ARRAY(otherLiteral)->count; i++) {
|
||||||
|
Toy_pushLiteralArray(TOY_AS_ARRAY(selfLiteral), TOY_AS_ARRAY(otherLiteral)->literals[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//return and clean up
|
||||||
|
Toy_pushLiteralArray(&interpreter->stack, selfLiteral);
|
||||||
|
|
||||||
|
Toy_freeLiteral(selfLiteral);
|
||||||
|
Toy_freeLiteral(otherLiteral);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TOY_IS_DICTIONARY(selfLiteral)) {
|
||||||
|
if (!TOY_IS_DICTIONARY(otherLiteral)) {
|
||||||
|
interpreter->errorOutput("Incorrect argument type passed to _concat (unknown type for other)\n");
|
||||||
|
Toy_freeLiteral(selfLiteral);
|
||||||
|
Toy_freeLiteral(otherLiteral);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//append each element of self to other, which will overwrite existing entries
|
||||||
|
for (int i = 0; i < TOY_AS_DICTIONARY(selfLiteral)->capacity; i++) {
|
||||||
|
if (!TOY_IS_NULL(TOY_AS_DICTIONARY(selfLiteral)->entries[i].key)) {
|
||||||
|
Toy_setLiteralDictionary(TOY_AS_DICTIONARY(otherLiteral), TOY_AS_DICTIONARY(selfLiteral)->entries[i].key, TOY_AS_DICTIONARY(selfLiteral)->entries[i].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//return and clean up
|
||||||
|
Toy_pushLiteralArray(&interpreter->stack, otherLiteral);
|
||||||
|
|
||||||
|
Toy_freeLiteral(selfLiteral);
|
||||||
|
Toy_freeLiteral(otherLiteral);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TOY_IS_STRING(selfLiteral)) { //a little redundant
|
||||||
|
if (!TOY_IS_STRING(otherLiteral)) {
|
||||||
|
interpreter->errorOutput("Incorrect argument type passed to _concat (unknown type for other)\n");
|
||||||
|
Toy_freeLiteral(selfLiteral);
|
||||||
|
Toy_freeLiteral(otherLiteral);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the combined length for the new string
|
||||||
|
int length = TOY_AS_STRING(selfLiteral)->length + TOY_AS_STRING(otherLiteral)->length + 1;
|
||||||
|
|
||||||
|
if (length > TOY_MAX_STRING_LENGTH) {
|
||||||
|
interpreter->errorOutput("Can't concatenate these strings, result is too long (error found in _concat)\n");
|
||||||
|
Toy_freeLiteral(selfLiteral);
|
||||||
|
Toy_freeLiteral(otherLiteral);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//allocate the space and generate
|
||||||
|
char* buffer = TOY_ALLOCATE(char, length);
|
||||||
|
snprintf(buffer, length, "%s%s", Toy_toCString(TOY_AS_STRING(selfLiteral)), Toy_toCString(TOY_AS_STRING(otherLiteral)));
|
||||||
|
|
||||||
|
Toy_Literal result = TOY_TO_STRING_LITERAL(Toy_createRefString(buffer));
|
||||||
|
|
||||||
|
//push and clean up
|
||||||
|
Toy_pushLiteralArray(&interpreter->stack, result);
|
||||||
|
|
||||||
|
TOY_FREE_ARRAY(char, buffer, length);
|
||||||
|
Toy_freeLiteral(selfLiteral);
|
||||||
|
Toy_freeLiteral(otherLiteral);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
interpreter->errorOutput("Incorrect argument type passed to _concat (unknown type for self)\n");
|
||||||
|
Toy_freeLiteral(selfLiteral);
|
||||||
|
Toy_freeLiteral(otherLiteral);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static int nativeGetKeys(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
static int nativeGetKeys(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||||
if (arguments->count != 1) {
|
if (arguments->count != 1) {
|
||||||
interpreter->errorOutput("Incorrect number of arguments to _getKeys\n");
|
interpreter->errorOutput("Incorrect number of arguments to _getKeys\n");
|
||||||
@@ -147,7 +256,7 @@ static void toStringUtil(const char* input) {
|
|||||||
int len = strlen(input) + 1;
|
int len = strlen(input) + 1;
|
||||||
|
|
||||||
if (len > TOY_MAX_STRING_LENGTH) {
|
if (len > TOY_MAX_STRING_LENGTH) {
|
||||||
len = TOY_MAX_STRING_LENGTH;
|
len = TOY_MAX_STRING_LENGTH; //TODO: don't truncate
|
||||||
}
|
}
|
||||||
|
|
||||||
toStringUtilObject = TOY_ALLOCATE(char, len);
|
toStringUtilObject = TOY_ALLOCATE(char, len);
|
||||||
@@ -362,7 +471,7 @@ typedef struct Natives {
|
|||||||
int Toy_hookCompound(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
int Toy_hookCompound(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) {
|
||||||
//build the natives list
|
//build the natives list
|
||||||
Natives natives[] = {
|
Natives natives[] = {
|
||||||
// {"_concat", native}, //array, dictionary, string
|
{"_concat", nativeConcat}, //array, dictionary, string
|
||||||
// {"_containsKey", native}, //dictionary
|
// {"_containsKey", native}, //dictionary
|
||||||
// {"_containsValue", native}, //array, dictionary
|
// {"_containsValue", native}, //array, dictionary
|
||||||
// {"_every", native}, //array, dictionary, string
|
// {"_every", native}, //array, dictionary, string
|
||||||
|
|||||||
@@ -1,6 +1,36 @@
|
|||||||
import compound;
|
import compound;
|
||||||
|
|
||||||
//test getKeys
|
//test array concat
|
||||||
var d = ["foo": 1, "bar": 2];
|
{
|
||||||
var a = d.getValues();
|
var a = [1, 2, 3];
|
||||||
print a;
|
var b = [4, 5, 6];
|
||||||
|
|
||||||
|
var c = a.concat(b).concat(b);
|
||||||
|
|
||||||
|
assert c == [1, 2, 3, 4, 5, 6, 4, 5, 6], "array.concat() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test dictionary concat
|
||||||
|
{
|
||||||
|
var a = ["one" : 1, "two": 2, "three": 3];
|
||||||
|
var b = ["four" : 4, "five": 5, "six": 6];
|
||||||
|
|
||||||
|
var c = a.concat(b);
|
||||||
|
|
||||||
|
assert c.length() == 6, "dictionary.concat().length() failed";
|
||||||
|
|
||||||
|
assert c == ["one" : 1, "two": 2, "three": 3, "four" : 4, "five": 5, "six": 6], "dictionary.concat() comparison failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test string concat
|
||||||
|
{
|
||||||
|
var a = "foo";
|
||||||
|
var b = "bar";
|
||||||
|
|
||||||
|
var c = a.concat(b);
|
||||||
|
|
||||||
|
assert c == "foobar", "string.concat() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
print "All good";
|
||||||
|
|||||||
@@ -1,5 +1,39 @@
|
|||||||
import compound;
|
import compound;
|
||||||
|
|
||||||
|
{
|
||||||
|
//test array concat
|
||||||
|
{
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
var b = [4, 5, 6];
|
||||||
|
|
||||||
|
var c = a.concat(b).concat(b);
|
||||||
|
|
||||||
|
assert c == [1, 2, 3, 4, 5, 6, 4, 5, 6], "array.concat() failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test dictionary concat
|
||||||
|
{
|
||||||
|
var a = ["one" : 1, "two": 2, "three": 3];
|
||||||
|
var b = ["four" : 4, "five": 5, "six": 6];
|
||||||
|
|
||||||
|
var c = a.concat(b);
|
||||||
|
|
||||||
|
assert c.length() == 6, "dictionary.concat().length() failed";
|
||||||
|
|
||||||
|
assert c == ["one" : 1, "two": 2, "three": 3, "four" : 4, "five": 5, "six": 6], "dictionary.concat() comparison failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
//test string concat
|
||||||
|
{
|
||||||
|
var a = "foo";
|
||||||
|
var b = "bar";
|
||||||
|
|
||||||
|
var c = a.concat(b);
|
||||||
|
|
||||||
|
assert c == "foobar", "string.concat() failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//test getKeys
|
//test getKeys
|
||||||
{
|
{
|
||||||
var d = ["foo": 1, "bar": 2];
|
var d = ["foo": 1, "bar": 2];
|
||||||
|
|||||||
Reference in New Issue
Block a user