/* Load boolean */ int cx_xmlnodeBool(cx_xmlnode cnode, unsigned int* out) { char* str; int result; xmlNodePtr node = (xmlNodePtr)cnode; cx_assert(out != 0, "Invalid out parameter."); result = -1; str = (char*)xmlNodeGetContent(node); if (str) { result = 0; if (!strcmp("true", str) || !strcmp("TRUE", str)) { *out = 1; } else if (!strcmp("false", str) || !strcmp("FALSE", str)){ *out = 0; } else { result = -1; cx_error("invalid boolean value '%s' in node '%s'.", str, node->name); } free(str); } else { cx_error("node '%s' has no content (expected integer).", node->name); } return result; }
void cx_parser::parse_case_label(cx_symtab_node* p_function_id, const cx_type *p_expr_type) { get_token_append(); bool sign_flag(false); if (token_in(token, tokenlist_unary_ops)) { sign_flag = true; get_token_append(); } switch (token) { case tc_identifier: if (!search_all(p_token->string__())) { cx_error(err_undefined_identifier); } get_token_append(); break; case tc_number: if (p_token->type() != ty_integer) cx_error(err_invalid_constant); get_token_append(); break; case tc_string: if (sign_flag || (strlen(p_token->string__()) != 3)) { cx_error(err_invalid_constant); } break; default: break; } conditional_get_token_append(tc_colon, err_missing_colon); parse_statement_list(p_function_id, tc_BREAK); }
/* Load boolean from attribute */ int cx_xmlnodeAttrBool(cx_xmlnode cnode, const char* attribute, unsigned int* out) { char* str; int result; xmlNodePtr node = (xmlNodePtr)cnode; cx_assert(out != 0, "Invalid out parameter."); result = -1; str = (char*)xmlGetProp(node, (xmlChar*)attribute); if (str) { result = 0; if (!strcmp("true", str) || !strcmp("TRUE", str) || !strcmp("True", str)) { *out = 1; } else if (!strcmp("false", str) || !strcmp("FALSE", str) || !strcmp("False", str)){ *out = 0; } else { result = -1; cx_error("invalid boolean value '%s' in attribute '%s' of node '%s'.", str, attribute, node->name); } free(str); } else { cx_error("boolean attribute '%s' not found in node '%s'.", attribute, node->name); } return result; }
/* Open xml file */ cx_xmlreader cx_xmlreaderNew(const char* file, const char* rootElement) { xmlDocPtr doc; xmlNodePtr root; cx_xmlreader reader; reader = 0; if (!xml_initialized) { xmlInitParser(); xml_initialized = TRUE; } doc = xmlParseFile(file); if (doc) { root = xmlDocGetRootElement(doc); assert(root); if (xmlStrcmp(root->name, (const xmlChar*)rootElement)) { cx_error("incorrect root element '%s' (expected '%s').", root->name, rootElement); xmlFreeDoc(doc); doc = 0; } else { reader = malloc(sizeof(cx_xmlreader_s)); reader->doc = doc; reader->root = root; } } return reader; }
int main(int argc, char* argv[]) { int i; /* Start database */ cx_start(); /* Parse arguments */ for(i=1; i<argc; i++) { if (*argv[i] == '-') { if (*(argv[i]+1) == 'd') { CX_DEBUG_ENABLED = TRUE; } } else { if (cx_load(argv[i])) { cx_error("cortex: failed to load file '%s'", argv[i]); goto error; } } } /* Stop database */ cx_stop(); return 0; error: return -1; }
/* ::cortex::lang::type::copy(any value) */ cx_int16 cx_type_copy(cx_any _this, cx_any value) { /* $begin(::cortex::lang::type::copy) */ cx_copy_ser_t data; struct cx_serializer_s s; cx_value v1; cx_int16 result; if (_this.type->reference || value.type->reference) { cx_valueObjectInit(&data.value, _this.value); cx_valueObjectInit(&v1, value.value); } else { cx_valueValueInit(&data.value, NULL, cx_type(_this.type), _this.value); cx_valueValueInit(&v1, NULL, cx_type(value.type), value.value); } s = cx_copy_ser(CX_PRIVATE, CX_NOT, CX_SERIALIZER_TRACE_ON_FAIL); result = cx_serializeValue(&s, &v1, &data); if (result) { cx_id id, id2; cx_error("type::copy: failed to copy value of type '%s' to value of type '%s'", cx_fullname(_this.type, id), cx_fullname(value.type, id2)); } return result; /* $end */ }
cx_int16 cx_type_bindMetaprocedure(cx_type _this, cx_metaprocedure procedure) { cx_function* f; cx_int32 d = 0; /* Check if function is overloaded */ if ((f = cx_vtableLookup(&_this->metaprocedures, cx_nameof(procedure), NULL, &d))) { if (d) { cx_function(*f)->overloaded = TRUE; /* Flag found and passed function as overloaded. */ cx_function(procedure)->overloaded = TRUE; } else { if (*f != cx_function(procedure)) { /* Overriding metaprocedures is not allowed. */ cx_id id, id2; cx_error("definition of metaprocedure '%s' conflicts with existing metaprocedure '%s'", cx_fullname(*f, id), cx_fullname(procedure, id2)); goto error; } } } if (cx_vtableInsert(&_this->metaprocedures, cx_function(procedure))) { cx_keep_ext(_this, procedure, "Bind metaprocedure to type."); } return 0; error: return -1; }
/** enter_new search the symbol table for the given name * string. If the name is not already in there, * enter it. Otherwise, flag the redefined * identifier error. * * @param p_string : ptr to name string to enter. * @param dc : definition code. * @return ptr to symbol table node. */ cx_symtab_node *cx_symtab::enter_new(const char *p_string, cx_define_code dc) { cx_symtab_node *p_node = search(p_string); if (!p_node) p_node = enter(p_string, dc); else cx_error(err_redefined_identifier); return p_node; }
/* ::cortex::io::file::construct() */ cx_int16 io_file_construct(io_file _this) { /* $begin(::cortex::io::file::construct) */ if (_this->name) {\ /* Special directive, for opening stdout, stdin and stderr */ if (*_this->name == '#') { if (!strcmp(_this->name, "#out")) { _this->handle = (cx_word)stdout; } else if (!strcmp(_this->name, "#in")) { _this->handle = (cx_word)stdin; } else if (!strcmp(_this->name, "#err")) { _this->handle = (cx_word)stderr; } else { cx_error("unknown file-directive '%s'", _this->name); goto error; } } else { if (!_this->binary) { switch(_this->mode) { case Io_Read: _this->handle = (cx_word)fopen(_this->name, "r"); break; case Io_Write: _this->handle = (cx_word)fopen(_this->name, "w"); break; case Io_Append: _this->handle = (cx_word)fopen(_this->name, "a"); break; default: cx_error("invalid filemode specified."); break; } } else { switch(_this->mode) { case Io_Read: _this->handle = (cx_word)fopen(_this->name, "rb"); break; case Io_Write: _this->handle = (cx_word)fopen(_this->name, "wb"); break; case Io_Append: _this->handle = (cx_word)fopen(_this->name, "ab"); break; default: cx_error("invalid filemode specified."); break; } } if (!_this->handle) { cx_error("failed to open file '%s'", _this->name); } } } else { cx_error("invalid filename."); goto error; } return 0; error: return -1; /* $end */ }
/* Define type */ static void cx_defineType(cx_object o, cx_uint32 size) { cx_defineObject(o); /* Size validation */ if (cx_type(o)->size != size) { cx_id id; cx_error("bootstrap: size validation failed for type '%s' - metatype = %d, c-type = %d.", cx_fullname(o, id), cx_type(o)->size, size); } }
/** enter_scope enter a new nested scope. Increment the nesting * level. push new scope's symbol table onto the * stack. * */ void cx_symtab_stack::enter_scope(void) { if (++current_nesting_level > max_nesting_level) { cx_error(err_nesting_too_deep); abort_translation(abort_nesting_too_deep); } set_current_symtab(new cx_symtab); }
/** find search the symbol table stack for the given * name string. If the name is not already in * there, flag the undefined identifier error, * and then enter the name into the local symbol * table. * * @param p_string : ptr to name string to find. * @return ptr to symbol table node. */ cx_symtab_node *cx_symtab_stack::find(const char *p_string) const { cx_symtab_node *p_node = search_all(p_string); if (!p_node) { cx_error(err_undefined_identifier); p_node = p_symtabs[current_nesting_level]->enter(p_string); } return p_node; }
/* Load string from attribute */ char* cx_xmlnodeAttrStr(cx_xmlnode cnode, const char* attribute) { char* str; xmlNodePtr node = (xmlNodePtr)cnode; str = (char*)xmlGetProp(node, (xmlChar*)attribute); if (!str) { cx_error("string attribute '%s' not found in node '%s'.", attribute, node->name); } return str; }
/* Load string */ char* cx_xmlnodeStr(cx_xmlnode cnode) { char* str; xmlNodePtr node = (xmlNodePtr)cnode; str = (char*)xmlNodeGetContent(node); if (!str) { cx_error("node %s has no content (expected string).", node->name); } return str; }
/** enter_scope enter a new nested scope. Increment the nesting * level. push new scope's symbol table onto the * stack. * */ void cx_symtab_stack::enter_scope(void) { // dont overwrite mains scope //if (current_nesting_level <= 1)++current_nesting_level; if (++current_nesting_level > max_nesting_level) { cx_error(err_nesting_too_deep); abort_translation(abort_nesting_too_deep); } set_current_symtab(new cx_symtab); }
/* ::cortex::lang::list::construct() */ cx_int16 cx_list_construct(cx_list _this) { /* $begin(::cortex::lang::list::construct) */ cx_type(_this)->hasResources = TRUE; cx_type(_this)->size = sizeof(cx_ll); cx_type(_this)->alignment = CX_ALIGNMENT(cx_ll); if (!cx_collection(_this)->elementType) { cx_error("no elementtype provided for list"); goto error; } return cx_type_construct(cx_type(_this)); error: return -1; /* $end */ }
/** parse_SWITCH parse switch statements. * * switch(<expression>){ * case <const-expression>: * default: * } * * NOTE: * Broken/not implemented yet. * * @param p_function_id : ptr to this statements function Id. */ void cx_parser::parse_SWITCH(cx_symtab_node* p_function_id) { get_token_append(); conditional_get_token_append(tc_left_paren, err_missing_left_paren); cx_type *p_expr_type = parse_expression()->base_type(); conditional_get_token_append(tc_right_paren, err_missing_right_paren); if ((p_expr_type != p_integer_type) && (p_expr_type != p_char_type) && (p_expr_type->form != fc_enum)) { cx_error(err_incompatible_types); } parse_statement(p_function_id); }
/* ::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 */ }
/* Load unsigned int */ int cx_xmlnodeUint(cx_xmlnode cnode, unsigned int* out) { char* str; int result; xmlNodePtr node = (xmlNodePtr)cnode; cx_assert(out != 0, "Invalid out parameter."); result = -1; str = (char*)xmlNodeGetContent(node); if (str) { *out = atoi(str); result = 0; } else { cx_error("node '%s' has no content (expected integer).", node->name); } return result; }
/* Load int */ float cx_xmlnodeFloat(cx_xmlnode cnode, float* out) { char* str; float result; xmlNodePtr node = (xmlNodePtr)cnode; cx_assert(out != 0, "Invalid out parameter."); result = -1; str = (char*)xmlNodeGetContent(node); if (str) { *out = (float)atof(str); result = 0; } else { cx_error("node '%s' has no content (expected float).", node->name); } return result; }
/* Load unsigned int from attribute */ int cx_xmlnodeAttrUint(cx_xmlnode cnode, const char* attribute, unsigned int* out) { char* str; int result; xmlNodePtr node = (xmlNodePtr)cnode; cx_assert(out != 0, "Invalid out parameter."); result = -1; str = (char*)xmlGetProp(node, (xmlChar*)attribute); if (str) { *out = atoi(str); free(str); result = 0; } else { cx_error("integer attribute '%s' not found in node '%s'.", attribute, node->name); } return result; }
/* Load float from attribute */ float cx_xmlnodeAttrFloat(cx_xmlnode cnode, const char* attribute, float* out) { char* str; float result; xmlNodePtr node = (xmlNodePtr)cnode; cx_assert(out != 0, "Invalid out parameter."); result = -1; str = (char*)xmlGetProp(node, (xmlChar*)attribute); if (str) { *out = (float)atof(str); free(str); result = 0; } else { cx_error("float attribute '%s' not found in node '%s'.", attribute, node->name); } return result; }
/* ::cortex::lang::constant::init() */ cx_int16 cx_constant_init(cx_constant *_this) { /* $begin(::cortex::lang::constant::init) */ cx_object parent; parent = cx_parentof(_this); /* Parent must be an enum */ if (cx_typeof(parent) == cx_type(cx_enum_o)) { cx__enum_bindConstant(parent, _this); } else if (cx_typeof(parent) == cx_type(cx_bitmask_o)) { cx__bitmask_bindConstant(parent, _this); } else { cx_id id; cx_error("::constant::init: parent of constant '%s' is not an enum.", cx_fullname(_this, id)); goto error; } return 0; error: return -1;/* $end */ }
static int cx_functionLookupWalk(cx_object o, void* userData) { cx_functionLookup_t* data; cx_int32 d; data = userData; if (o != data->f) { if ((cx_class_instanceof(cx_procedure_o, cx_typeof(o)))) { if (cx_overload(o, cx_nameof(data->f), &d, FALSE)) { data->error = TRUE; goto finish; } /* Check if function matches */ if (!d) { cx_id id, id2; cx_error("function '%s' conflicts with existing declaration '%s'", cx_fullname(data->f, id), cx_fullname(o, id2)); data->error = TRUE; goto finish; } else { cx_id id; /* Get name of function */ cx_signatureName(cx_nameof(o), id); /* Set overloading flags if a function with same name is found. */ if (!strcmp(data->name, id)) { cx_function(o)->overloaded = TRUE; data->f->overloaded = TRUE; } } } } return 1; finish: return 0; }
/* ::cortex::lang::struct::construct() */ cx_int16 cx_struct_construct(cx_struct _this) { /* $begin(::cortex::lang::struct::construct) */ cx_struct base; cx_uint16 alignment; cx_uint32 size; size = 0; alignment = 0; /* Insert members */ if (cx__interface_insertMembers(cx_interface(_this))) { goto error; } /* Calculate alignment of self */ if (cx_interface(_this)->members.length) { alignment = cx__interface_calculateAlignment(cx_interface(_this)); if (!alignment) { cx_id id; cx_error("error in definition of '%s'", cx_fullname(_this, id)); goto error; } } /* Check if struct inherits from another struct */ base = (cx_struct)cx_interface(_this)->base; /* Get maximum alignment from self and base-class and copy template parameters */ if (base) { if (!cx_instanceof(cx_type(cx_struct_o), base)) { cx_id id, id2; cx_error("struct '%s' inherits from non-struct type '%s'", cx_fullname(_this, id), cx_fullname(base, id2)); goto error; } if (cx_type(base)->alignment) { if (alignment < cx_type(base)->alignment) { alignment = cx_type(base)->alignment; } } } /* Set alignment of self */ cx_type(_this)->alignment = alignment; /* Get size of base-class */ if (base) { size = cx_type(base)->size; if (cx_type(base)->hasResources) { cx_type(_this)->hasResources = TRUE; } } /* Calculate size of self */ if (cx_interface(_this)->members.length) { size = cx__interface_calculateSize(cx_interface(_this), size); if (!size) { cx_id id; cx_error("error in definition of '%s'", cx_fullname(_this, id)); goto error; } } /* Set size of self */ cx_type(_this)->size = size; return cx_interface_construct(cx_interface(_this)); error: return -1; /* $end */ }
/* Define object */ static void cx_defineObject(cx_object o) { if (cx_define(o)) { cx_error("construction of builtin-object '%s' failed.", cx_nameof(o)); } }
/* ::cortex::lang::function::stringToParameterSeq(string name,object scope) */ cx_parameterSeq cx_function_stringToParameterSeq(cx_string name, cx_object scope) { /* $begin(::cortex::lang::function::stringToParameterSeq) */ cx_parameterSeq result = {0, NULL}; cx_char* ptr; ptr = strchr(name, '('); if (!ptr) { cx_error("missing argumentlist in name for signature '%s'", name); goto error; } ptr++; /* Check if function has arguments */ if (*ptr != ')') { cx_int32 count = 0, i = 0; cx_id id; int flags = 0; /* Count number of parameters for function */ count = cx_signatureParamCount(name); if (count == -1) { goto error; } /* Allocate size for parameters */ result.length = count; result.buffer = cx_malloc(sizeof(cx_parameter) * count); memset(result.buffer, 0, sizeof(cx_parameter) * count); /* Parse arguments */ for(i=0; i<count; i++) { if (cx_signatureParamType(name, i, id, &flags)) { cx_error("error occurred while parsing type of parameter '%d' for signature '%s'", i, name); goto error; } /* Set reference */ result.buffer[i].passByReference = (flags & CX_PARAMETER_REFERENCE) != 0; /* Assign type */ result.buffer[i].type = cx_resolve_ext(NULL, scope, id, FALSE, "Resolve parameter-type for function"); if (!result.buffer[i].type) { cx_error("type '%s' of parameter %d in signature %s not found", id, i, name); goto error; } /* Validate whether reference is not redundantly applied */ if (result.buffer[i].passByReference && result.buffer[i].type->reference) { cx_id id; cx_error("redundant '&' qualifier for parameter %d, type '%s' is already a reference", i, cx_fullname(result.buffer[i].type, id)); goto error; } /* Parse name */ if (cx_signatureParamName(name, i, id)) { cx_error("error occurred while parsing name of argument '%s' for signature '%s'", name); goto error; } result.buffer[i].name = cx_strdup(id); } } return result; error: result.length = -1; cx_dealloc(result.buffer); result.buffer = NULL; return result; /* $end */ }