Exemple #1
0
/* TODO this is copy-paste from dbsh.c */
static char* dbsh_attrStr(cx_object o, char* buff) {
    cx_bool first;
    *buff = '\0';

    first = TRUE;
    if (cx_checkAttr(o, CX_ATTR_SCOPED)) {
        strcat(buff, "S");
        first = FALSE;
    }
    if (cx_checkAttr(o, CX_ATTR_WRITABLE)) {
        if (!first) {
            strcat(buff, "|W");
        } else {
            strcat(buff, "W");
            first = FALSE;
        }
    }
    if (cx_checkAttr(o, CX_ATTR_OBSERVABLE)) {
        if (!first) {
            strcat(buff, "|O");
        } else {
            strcat(buff, "O");
            first = FALSE;
        }
    }
    if (cx_checkAttr(o, CX_ATTR_PERSISTENT)) {
        if (!first) {
            strcat(buff, "|P");
        } else {
            strcat(buff, "P");
        }
    }
    return buff;
}
int cx_genCollectAnonymous(void* o, void* userData) {
    cx_ll list = userData;

    if (!cx_checkAttr(o, CX_ATTR_SCOPED)) {
        cx_llInsert(list, o);
    }

    return 1;
}
Exemple #3
0
/* Handle subscribe message */
static int web_subscribe(struct mg_connection *conn) {
    char *flag_start = conn->content + 2;
    char *id_start = strchr(flag_start, ' ') + 1;
    int len;
    cx_id id;
    cx_object o = NULL;
    web_wsconnection wc = web_wsconnection(conn->connection_param);

    /* Check if message is correct */
    if ((id_start - conn->content) > (int)conn->content_len) {
        printf("error: message '%.*s' not correctly formatted\n",
            (int)conn->content_len, conn->content);
        goto error;
    }

    /* Copy identifier to buffer */
    len = (int)conn->content_len - (id_start - conn->content);
    memcpy(id, id_start, len);
    id[len] = '\0';

    /* Silence previous subscription */
    if (wc->observing) {
        cx_silence(wc->observing, web_wsconnection_onUpdate_o, wc);
        cx_silence(wc->observing, web_wsconnection_onDelete_o, wc);
    }
    wc->eventCount = 0;

    /* Lookup object */
    o = cx_resolve(NULL, id);
    if (!o) {
        goto error;
    } else if (!cx_checkAttr(o, CX_ATTR_OBSERVABLE)) {
        /* Can't listen if object is not observable, but can send the client the value */
        cx_set(&wc->observing, NULL);
        web_wsconnection_send(wc, o, TRUE, TRUE, TRUE, TRUE, FALSE);
        wc->eventCount++;
    } else {
        /* Configure observer to listen for updates */
        cx_set(&wc->observing, o);
        cx_listen(o, web_wsconnection_onUpdate_o, wc);
        cx_listen(o, web_wsconnection_onDelete_o, wc);
    }
    
    return 0;
error:
    return -1;
}
Exemple #4
0
/* ::cortex::lang::type::parentof() */
cx_object cx_type_parentof(cx_any _this) {
/* $begin(::cortex::lang::type::parentof) */
    cx_string result = NULL;

   if (cx_checkAttr(_this.value, CX_ATTR_SCOPED)) {
       result = cx_parentof(_this.value);
   } else {
       cx_id id;
       cx_error("cannot get parent from non-scoped object of type '%s'", cx_fullname(cx_typeof(_this.value), id));
   }
    
   if (result) {
       cx_keep(result);
   }

   return result;
/* $end */
}
/* ::cortex::Fast::StaticInitializer::define() */
cx_int16 Fast_StaticInitializer_define(Fast_StaticInitializer _this) {
/* $begin(::cortex::Fast::StaticInitializer::define) */
    cx_uint32 variable;
    cx_object o;

    /* Types are defined during 1st pass. All other objects are defined when a program starts. Defining types
     * at compile-time is required to do validity checking while parsing. On the other hand, objects cannot be
     * defined at compile-time because class constructors\destructors are not yet defined at that point. This
     * would cause object creation\destruction without calling the appropriate constructors\destructors.
     */
    for(variable=0; variable<Fast_Initializer(_this)->variableCount; variable++) {
        o = (cx_object)Fast_Object(Fast_Initializer(_this)->variables[variable].object)->value;
        if (cx_instanceof(cx_type(cx_type_o), o)
                || (cx_checkAttr(o, CX_ATTR_SCOPED) && cx_instanceof(cx_type(cx_type_o), cx_parentof(o)))) {
            if (cx_define(o)) {
                cx_id id1, id2;
                Fast_Parser_error(yparser(), "define of variable '%s' of type '%s' failed",
                        Fast_Parser_id(o, id1),
                        Fast_Parser_id(cx_typeof(o), id2));
                goto error;
            }
        } else {
            Fast_Expression refVar = Fast_Expression(Fast_Object__create(o));
            refVar->isReference = TRUE; /* Always treat object as reference */
            Fast_Define defineStmt = Fast_Define__create(refVar);
            Fast_Parser_addStatement(yparser(), Fast_Node(defineStmt));
            Fast_Parser_collect(yparser(), defineStmt);
            Fast_Parser_collect(yparser(), refVar);
        }
    }
    
    Fast_Initializer_define_v(Fast_Initializer(_this));

    return 0;
error:
    return -1;
/* $end */
}
Exemple #6
0
static cx_int16 serializeReference(cx_serializer s, cx_value *v, void *userData) {
    CX_UNUSED(s);

    cx_json_ser_t *data;
    void *o;
    cx_object object;
    cx_id id;

    data = userData;
    o = cx_valueValue(v);
    object = *(cx_object*)o;

    if (object) {
        if (cx_checkAttr(object, CX_ATTR_SCOPED) || (cx_valueObject(v) == object)) {
            cx_uint32 length;
            cx_fullname(object, id);
            
            /* Escape value */
            cx_string escapedValue = cx_malloc((length = stresc(NULL, 0, id)) + 1);
            stresc(escapedValue, length, id);
            if (!cx_ser_appendstr(data, "\"@R %s\"", escapedValue)) {
                cx_dealloc(escapedValue);
                goto finished;
            }
            cx_dealloc(escapedValue);
        } else {
            cx_ser_appendstr(data, "\"anonymous\"");
        }
    } else {
        if (!cx_ser_appendstrbuff(data, "null")) {
            goto finished;
        }
    }
    return 0;
finished:
    return 1;

}
/* Serialize dependencies on references */
cx_int16 cx_genDepReference(cx_serializer s, cx_value* info, void* userData) {
    cx_object o;
    g_depWalk_t data;

    CX_UNUSED(s);

    data = userData;
    o = *(cx_object*)cx_valueValue(info);

    if (o && g_mustParse(data->data->g, o)) {
        cx_member m;

        m = NULL;

        if (info->kind == CX_MEMBER) {
            m = info->is.member.t;
            if (!m->type->reference) {
                m = NULL;
            }
        }

        /* Add dependency on item */
        if (m) {
            cx_depresolver_depend(data->data->resolver, data->o, CX_DEFINED, o, m->state);
        } else {
            cx_depresolver_depend(data->data->resolver, data->o, CX_DEFINED, o, CX_DEFINED);
        }

        /* Include dependencies on anonymous types */
        if (!cx_checkAttr(o, CX_ATTR_SCOPED)) {
            cx_genDepBuildAction(o, data->data);
        }
    }

    return 0;
}
/* Build dependency-administration for object */
int cx_genDepBuildAction(cx_object o, void* userData) {
    g_itemWalk_t data;
    struct g_depWalk_t walkData;
    struct cx_serializer_s s;
    int result;
    cx_object parent = NULL;

    if (cx_checkAttr(o, CX_ATTR_SCOPED)) {
        parent = cx_parentof(o);
    }

    data = userData;

    /* If object is cortex_lang_o, signal that a bootstrap is found, indicating
     * that dependencies should be disregarded. */
    if (o == cortex_lang_o) {
        data->bootstrap = TRUE;
        result = 0;
    } else {
        /* Insert type-dependency: object can be declared only after it's type is defined. */
        if (g_mustParse(data->g, cx_typeof(o))) {
            cx_depresolver_depend(data->resolver, o, CX_DECLARED, cx_typeof(o), CX_DEFINED);
        }

        /* TODO: this is not nice */
        if (cx_class_instanceof(cx_procedure_o, cx_typeof(o))) {
            /* Insert base-dependency: methods may only be declared after the base of a class has been defined. */
            if (cx_typeof(o) != cx_type(cx_function_o)) {
                if (cx_class_instanceof(cx_class_o, parent) && cx_interface(parent)->base) {
                    if (g_mustParse(data->g, cx_interface(parent)->base)) {
                        cx_depresolver_depend(data->resolver, o, CX_DECLARED, cx_interface(parent)->base, CX_DEFINED);
                    }
                }
            }

            /* Add dependencies on function parameters - types must be declared before function is declared. */
            if (cx_genDepBuildProc(cx_function(o), data)) {
                goto error;
            }
        }

        /* Insert dependency on parent */
        if (cx_checkAttr(o, CX_ATTR_SCOPED)) {
            if (parent != root_o) { /* Root is always available */
                cx_int8 parentState = cx_type(cx_typeof(o))->parentState;

                cx_depresolver_depend(data->resolver, o, CX_DECLARED, parent, parentState);
                if (parentState == CX_DECLARED) {
                    cx_depresolver_depend(data->resolver, parent, CX_DEFINED, o, CX_DEFINED);
                }
            }
        }

        /* Insert dependencies on references in the object-value */
        walkData.o = o;
        walkData.data = data;
        s = cx_genDepSerializer();
        if (cx_serialize(&s, o, &walkData)) {
            goto error;
        }

        result = 1;
    }

    return result;
error:
    return 0;
}
Exemple #9
0
static cx_int16 serializeMeta(cx_serializer s, cx_value* v, void* userData) {
    CX_UNUSED(s);
    cx_json_ser_t *data = userData;
    cx_object o = cx_valueValue(v);

    if (!data->serializeMeta) {
        goto error;
    }

    if (!cx_ser_appendstr(userData, "{")) {
        goto finished;
    }

    cx_string name = cx_nameof(o);
    if (name) {
        if (!cx_appendStringAttr("name", name, userData)) {
            goto finished;
        }
    } else {
        if (!cx_ser_appendstr(userData, "\"name\":\"::\",")) {
            goto finished;
        }        
    }

    cx_id type_fullname;
    cx_fullname(cx_typeof(o), type_fullname);
    if (!cx_appendStringAttr("type", type_fullname, userData)) {
        goto finished;
    }

    if (cx_checkAttr(o, CX_ATTR_PERSISTENT)) {
        cx_time t = cx_timestampof(o);
        if (!cx_ser_appendstr(data, "\"timestamp\":\"%d.%.9d\",", t.tv_sec, t.tv_nsec)) {
            goto finished;
        }        
    }

    char states[sizeof("V|DCL|DEF")];
    dbsh_stateStr(o, states);
    if (!cx_ser_appendstr(data, "\"states\":\"%s\",", states)) {
        goto finished;
    }

    char attributes[sizeof("S|W|O|P")];
    dbsh_attrStr(o, attributes);
    if (!cx_ser_appendstr(data, "\"attributes\":\"%s\",", attributes)) {
        goto finished;
    }

    cx_id parent_fullname;
    cx_fullname(cx_parentof(o), parent_fullname);
    if (!cx_ser_appendstr(data, "\"parent\":\"%s\",", parent_fullname)) {
        goto finished;
    }

    cx_uint32 scopeSize = cx_scopeSize(o);
    if (!cx_ser_appendstr(data, "\"childCount\":%"PRId32"", scopeSize)) {
        goto finished;
    }

    if (!cx_ser_appendstr(data, "}")) {
        goto finished;
    }


    return 0;
error:
    return -1;
finished:
    return 1;
}
Exemple #10
0
/* ::cortex::lang::type::checkAttr(attr attributes) */
cx_bool cx_type_checkAttr(cx_any _this, cx_attr attributes) {
/* $begin(::cortex::lang::type::checkAttr) */
    return cx_checkAttr(_this.value, attributes);
/* $end */
}