/* Walk embedded expressions in string */ cx_int16 Fast_String_parse(Fast_String _this) { cx_char *ptr, ch, *str; Fast_String element; ptr = _this->value; str = ptr; /* Keep track of beginning of string-element */ if (ptr) { /* Walk string, split embedded expressions */ while((ch = *ptr)) { switch(ch) { case '$': /* Insert string-element */ if (str != ptr) { *ptr = '\0'; element = Fast_String__create(str); cx_llAppend(_this->elements, element); *ptr = ch; } /* Parse embedded expression */ str = ptr = Fast_String_parseEmbedded(_this, ptr+1); if (!ptr) { yparser()->line = Fast_Node(_this)->line; yparser()->column = Fast_Node(_this)->column; Fast_Parser_error(yparser(), "parsing string '%s' failed", _this->value); goto error; } break; default: ptr++; break; } } /* If string contains embedded expressions, add last bit of remaining * string to elements list */ if ((str != _this->value) && *str) { element = Fast_String__create(str); cx_llAppend(_this->elements, element); } } else { element = Fast_String__create("null"); cx_llAppend(_this->elements, element); } return 0; error: return -1; }
/* ::cortex::Fast::Expression::fromList(list{Expression} list) */ Fast_Expression Fast_Expression_fromList(Fast_Expression_list list) { /* $begin(::cortex::Fast::Expression::fromList) */ Fast_Expression result = NULL; /* Convert list to comma expression */ if (list) { if (cx_llSize(list) == 1) { result = cx_llGet(list, 0); } else { cx_ll toList = cx_llNew(); /* Copy list */ cx_iter iter; Fast_Expression expr; result = Fast_Expression(Fast_Comma__create()); iter = cx_llIter(list); while(cx_iterHasNext(&iter)) { expr = cx_iterNext(&iter); cx_llAppend(toList, expr); cx_keep_ext(result, expr, "add expression from list to comma-expression"); } Fast_Comma(result)->expressions = toList; Fast_Parser_collect(yparser(), result); } } return result; /* $end */ }
/* ::cortex::ic::program::pushScope() */ ic_scope ic_program_pushScope(ic_program _this) { /* $begin(::cortex::ic::program::pushScope) */ _this->scope = ic_scope__create(_this->scope, FALSE); if (_this->scope->parent) { cx_llAppend(_this->scope->parent->program, _this->scope); } return _this->scope; /* $end */ }
/* Run the server in a separate thread */ void* web_run(void *data) { struct mg_server *server; web_server _this = data; char portStr[6]; sprintf(portStr, "%u", _this->port); cx_event e; cx_ll events = cx_llNew(); // Create and configure the server server = mg_create_server(_this, web_handler); mg_set_option(server, "listening_port", portStr); // Serve request. Hit Ctrl-C to terminate the program for (;;) { mg_poll_server(server, 50); if (_this->exiting) { break; } /* Handle queued events */ cx_lock(_this); while ((e = cx_llTakeFirst(_this->events))) { cx_llAppend(events, e); } cx_unlock(_this); /* Process events outside of lock */ while ((e = cx_llTakeFirst(events))) { cx_event_handle(e); cx_free(e); mg_poll_server(server, 1); } } // Cleanup, and free server instance mg_destroy_server(&server); return NULL; }
/* $end */ cx_void web_server_post(web_server _this, cx_event e) { /* $begin(::cortex::web::server::post) */ cx_uint32 size = 0; cx_observableEvent e2; cx_lock(_this); /* Check if there is already another event in the queue for the same object. * if so, replace event with latest update. */ if ((e2 = web_server_findRelatedEvent(_this, cx_observableEvent(e)))) { cx_llReplace(_this->events, e2, e); cx_free(e2); } else { cx_llAppend(_this->events, e); } size = cx_llSize(_this->events); cx_unlock(_this); /* If queue is getting big, slow down publisher */ if (size > 100) { cx_sleep(0, 10000000); } /* $end */ }
static void* cx_list_do_(cx_any object, cx_bool insert) { cx_ll list = *(cx_ll*)object.value; void* value = NULL; cx_value dst; if (cx_collection_elementRequiresAlloc(cx_collection(object.type))) { cx_uint32 size = cx_type_sizeof(cx_collection(object.type)->elementType); value = cx_calloc(size); cx_valueValueInit(&dst, NULL, cx_collection(object.type)->elementType, value); cx_initValue(&dst); } else { value = NULL; cx_valueValueInit(&dst, NULL, cx_collection(object.type)->elementType, &value); cx_initValue(&dst); } if (insert) { cx_llInsert(list, value); } else { cx_llAppend(list, value); } return value; }
/* Parse embedded expression */ cx_char *Fast_String_parseEmbedded(Fast_String _this, cx_char *expr) { cx_char ch, *ptr; cx_uint32 nesting; Fast_Expression element; cx_bool bracketExpr = FALSE; if (!maskSet) { cx_tokenMaskSet(alphaMask, ":abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"); cx_tokenMaskSet(numericMask, "0123456789"); } ptr = expr; if (*ptr == '{') { bracketExpr = TRUE; expr = ++ptr; /* Progress expression as well to skip the initial '{' */ nesting = 1; while((ch = *ptr) && nesting) { switch(ch) { case '{': nesting++; break; case '}': nesting--; break; } ptr++; } ptr--; /* Skip the last '{' */ } else { /* If character is not a '{' parse a variable-name which is * delimited by a non-alphanumeric character. Additionally * variable names cannot start with a number. */ if (!alphaMask[(int)*ptr]) { yparser()->line = Fast_Node(_this)->line; yparser()->column = Fast_Node(_this)->column; Fast_Parser_error(yparser(), "invalid embedded expression at '%s'", expr); goto error; } ptr++; while((ch = *ptr) && (alphaMask[(int)ch] || numericMask[(int)ch])) { if (ch == ':') { ptr++; if (*ptr != ':') { ptr--; break; } } ptr++; } } ch = *ptr; *ptr = '\0'; element = Fast_Parser_parseExpression(yparser(), expr, _this->block, _this->scope, Fast_Node(_this)->line, Fast_Node(_this)->column); if (element) { cx_llAppend(_this->elements, element); cx_keep(element); } else { goto error; } *ptr = ch; if (bracketExpr) { ptr++; } return ptr; error: return NULL; }
static void cx_list_appendAction(cx_ll list, void *value, void *userData) { CX_UNUSED(userData); cx_llAppend(list, value); }
cx_word Fast_Initializer_offset(Fast_StaticInitializer _this, cx_uint32 variable) { cx_word result, base; cx_uint16 fp = Fast_Initializer(_this)->fp; Fast_InitializerFrame *frame = &Fast_Initializer(_this)->frames[fp?fp-1:0]; Fast_StaticInitializerFrame *baseFrame = &(_this->frames[fp?fp-1:0]); Fast_InitializerFrame *thisFrame = &Fast_Initializer(_this)->frames[fp]; result = 0; base = baseFrame->ptr[variable]; if (!base) { Fast_Parser_error(yparser(), "parser error: base is zero in offset calculation"); goto error; } /* Switch on current type */ switch(frame->type->kind) { case CX_PRIMITIVE: result = base; break; case CX_COMPOSITE: if (fp) { result = base + thisFrame->member->offset; } else { result = base; } break; case CX_ITERATOR: result = base; break; case CX_COLLECTION: { if (fp) { cx_uint32 elementSize = cx_type_sizeof(cx_collection(frame->type)->elementType); switch(cx_collection(frame->type)->kind) { case CX_SEQUENCE: ((cx_objectSeq*)base)->length++; ((cx_objectSeq*)base)->buffer = cx_realloc(((cx_objectSeq*)base)->buffer, ((cx_objectSeq*)base)->length * elementSize); base = (cx_word)((cx_objectSeq*)base)->buffer; case CX_ARRAY: result = base + thisFrame->location * cx_type_sizeof(cx_collection(frame->type)->elementType); memset((void*)result, 0, elementSize); break; case CX_LIST: { if (cx_collection_elementRequiresAlloc(cx_collection(frame->type))) { result = (cx_word)cx_calloc(elementSize); } if (!*(cx_ll*)base) { *(cx_ll*)base = cx_llNew(); } cx_llAppend(*(cx_ll*)base, (void*)result); if (!result) { result = (cx_word)cx_llGetPtr(*(cx_ll*)base, cx_llSize(*(cx_ll*)base)-1); } break; } case CX_MAP: { cx_type keyType = cx_map(frame->type)->keyType; if (!thisFrame->isKey) { if (cx_collection_elementRequiresAlloc(cx_collection(frame->type))) { result = (cx_word)cx_calloc(elementSize); } if (!*(cx_rbtree*)base) { *(cx_rbtree*)base = cx_rbtreeNew(frame->type); } cx_rbtreeSet(*(cx_rbtree*)base, (void*)_this->frames[fp].keyPtr[variable], (void*)result); if (!result) { if (_this->frames[fp].keyPtr[variable]) { result = (cx_word)cx_rbtreeGetPtr(*(cx_rbtree*)base, (void*)_this->frames[fp].keyPtr[variable]); } else { Fast_Parser_error(yparser(), "cannot set element without keyvalue"); goto error; } } } else { result = (cx_word)cx_calloc(cx_type_sizeof(keyType)); _this->frames[fp].keyPtr[variable] = result; thisFrame->isKey = FALSE; } break; } } } else { result = base; } break; } default: { cx_id id; Fast_Parser_error(yparser(), "invalid initializer type '%s'", Fast_Parser_id(frame->type, id)); break; } } return result; error: return 0; }