Skip to content

Distinguishing reference types and iterating over object properties #43

@iamtakingiteasy

Description

@iamtakingiteasy

Hi, i am trying to write native printing function, which takes any kind of JS value and prints it out, recursing into arrays and objects, also wrapping strings into quotes.

This is what i came up with:

UPD1: replaced flag checking with mxIsFunction, xsTypeOf with mxIs* and fxIs* functions, started taking into account String() object as well as primitive strings. Old version is at https://gist.github.com/iamtakingiteasy/ce4ffe33674d56234c446fc73c401998

#include <xs/xsAll.h>
#include <xs.h>
#include <stdio.h>

void hinarin_root_print(xsMachine *the) {
    for (xsIntegerValue i = 0; i < xsToInteger(xsArgc); i++) {
        if (i > 0) {
            printf(" ");
        }
        txSlot *instance = &xsArg(i);
        if (mxIsReference(instance)) {
            txSlot *reference = instance->value.reference;
            if (fxIsArray(the, reference)) { // seems OK, but why fx* and not mx* ?
                printf("[");
                for (txIndex d = 0; d < reference->next->value.array.length; d++) {
                    if (d > 0) {
                        printf(", ");
                    }
                    xsCallFunction1(xsGet(xsGlobal, xsID("print")), xsNull, reference->next->value.array.address[d]);
                }
                printf("]");
            } else if (reference->next == NULL) { // is this a correct way to detect plain {} object?
                printf("{");
                for (txSlot *next = reference->next; next; next = next->next) { // is this a correct way to iterate over object properties?
                    if (next != reference->next) {
                        printf(", ");
                    }
                    printf("%s: ", xsName(next->ID));
                    xsCallFunction1(xsGet(xsGlobal, xsID("print")), xsNull, *next);
                }
                printf("}");
            } else if (mxIsFunction(reference)) {
                char *name = "";
                if (reference->next->ID != XS_NO_ID) {
                    name = xsName(reference->next->ID); //appears to be a function name
                }
                printf("function %s() { ... }", name);
            } else if (mxIsString(reference)) {
                printf("\"%s\"", reference->next->value.string);
            } else {
                printf("%s", xsToString(*instance));
            }
        } else if (mxIsStringPrimitive(instance)) {
            printf("\"%s\"", instance->value.string);
        } else {
            printf("%s", xsToString(*instance));
        }
    }
}

void hinarin_root_println(xsMachine *the) {
    hinarin_root_print(the);
    printf("\n");
}

void hinarin_bind_root(xsMachine *the) {
    xsDefine(xsGlobal, xsID("print"), xsNewHostFunction(hinarin_root_print, 1), xsChangeAll);
    xsDefine(xsGlobal, xsID("println"), xsNewHostFunction(hinarin_root_println, 1), xsChangeAll);
}

but I have a few questions, which are outlined in comments to code, thanks.
Also: what XS_STRING_X_KIND and XS_CODE_X_KIND kinds are meaning and how they are different from XS_STRING_KIND and XS_CODE_KIND kinds? And i see that it is possible to get number of function arguments: reference->next->next->next->value.integer, but is it possible to get function argument names?

P.S. Any hints on how to do common things and what can be done better with XS6 are also quite welcome.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions