/* ParseExpr7 - handle the '<', '<=', '>=' and '>' operators */ static ParseTreeNode *ParseExpr7(ParseContext *c) { ParseTreeNode *expr, *expr2; int tkn; expr = ParseExpr8(c); while ((tkn = GetToken(c)) == '<' || tkn == T_LE || tkn == T_GE || tkn == '>') { int op; expr2 = ParseExpr8(c); switch (tkn) { case '<': op = OP_LT; break; case T_LE: op = OP_LE; break; case T_GE: op = OP_GE; break; case '>': op = OP_GT; break; default: /* not reached */ op = 0; break; } expr = MakeBinaryOpNode(c, op, expr, expr2); } SaveToken(c,tkn); return expr; }
bool mqtt_async::MqttClient::Publish(const std::string& topic, const void* payload, INT32 len, int qos, int retained/*default=0*/, const ActDoneCB& cb) { MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; Token* tok = nullptr; std::shared_ptr<Token> stok; TRACE("mqtt_async::MqttClient::Publish"); if (cb) { TRACE("mqtt_async::MqttClient::Publish with callback"); tok = new Token(this); stok = std::shared_ptr<Token>(tok); stok->act_done_cb = cb; SaveToken(stok); } opts.onSuccess = cb?&Token::OnSuccess : nullptr ; opts.onFailure = cb?&Token::OnFailed : nullptr ; opts.context = tok; MQTTAsync_message pubmsg = MQTTAsync_message_initializer; pubmsg.payload = const_cast<void*>(payload); pubmsg.payloadlen = len; pubmsg.qos = qos; pubmsg.retained = retained; int rc = MQTTAsync_sendMessage(client, (char*)topic.c_str(), &pubmsg, &opts) ; if (rc != MQTTASYNC_SUCCESS) { if (tok) RemoveToken(tok); TRACE("mqtt_async::MqttClient::Publish return false"); return false; } return true; }
main() { dataBlockT db; string line, cmd, token, var; int pos; printf("List structure test program\n"); printf("Type \"help\" for help\n"); db = NewDataBlock(); while (TRUE) { printf(">"); line = GetLine(); SetScannerString(db->scanner, line); cmd = ConvertToLowerCase(ReadToken(db->scanner)); if (IsVariableName(cmd)) { var = cmd; token = ReadToken(db->scanner); if (StringEqual(token, "")) { DisplayStringList(GetValue(db, var)); } else if (StringEqual(token, "=")) { ParseOperation(db, var); } else { Error("Unexpected token %s", token); } } else if (StringEqual(cmd, "help")) { HelpCmd(); } else if (StringEqual(cmd, "quit")) { break; } else { SaveToken(db->scanner, cmd); ParseOperation(db, NULL); } } }
/* ParseArrayInitializers - parse array initializers */ static void ParseArrayInitializers(ParseContext *c, VMVALUE size) { VMVALUE *dataPtr = (VMVALUE *)c->codeBuf; VMVALUE *dataTop = (VMVALUE *)c->ctop; int done = VMFALSE; Token tkn; FRequire(c, '{'); /* handle each line of initializers */ while (!done) { int lineDone = VMFALSE; /* look for the first non-blank line */ while ((tkn = GetToken(c)) == T_EOL) { if (!GetLine(c)) ParseError(c, "unexpected end of file in initializers"); } /* check for the end of the initializers */ if (tkn == '}') break; SaveToken(c, tkn); /* handle each initializer in the current line */ while (!lineDone) { ParseTreeNode *expr; /* get a constant expression */ expr = ParseExpr(c); if (!IsIntegerLit(expr)) ParseError(c, "expecting a constant expression"); /* check for too many initializers */ if (--size < 0) ParseError(c, "too many initializers"); /* store the initial value */ if (dataPtr >= dataTop) ParseError(c, "insufficient object data space"); *dataPtr++ = expr->u.integerLit.value; switch (tkn = GetToken(c)) { case T_EOL: lineDone = VMTRUE; break; case '}': lineDone = VMTRUE; done = VMTRUE; break; case ',': break; default: ParseError(c, "expecting a comma, right brace or end of line"); break; } } } }
/* ParseExpr6 - handle the '=' and '<>' operators */ static ParseTreeNode *ParseExpr6(ParseContext *c) { ParseTreeNode *expr, *expr2; int tkn; expr = ParseExpr7(c); while ((tkn = GetToken(c)) == '=' || tkn == T_NE) { int op; expr2 = ParseExpr7(c); switch (tkn) { case '=': op = OP_EQ; break; case T_NE: op = OP_NE; break; default: /* not reached */ op = 0; break; } expr = MakeBinaryOpNode(c, op, expr, expr2); } SaveToken(c,tkn); return expr; }
bool mqtt_async::MqttClient::Subscribe(string topic, int qos, const ActDoneCB& cb) { MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer; Token* tok = nullptr; std::shared_ptr<Token> stok; if (cb) { tok = new Token(this); stok = std::shared_ptr<Token>(tok); stok->act_done_cb = cb; SaveToken(stok); } opts.onSuccess = cb?&Token::OnSuccess : nullptr ; opts.onFailure = cb?&Token::OnFailed : nullptr ; opts.context = tok; int rc; if ((rc = MQTTAsync_subscribe(client, topic.c_str(), qos, &opts)) != MQTTASYNC_SUCCESS) { if (tok) RemoveToken(tok); return false; } return true; }
bool mqtt_async::MqttClient::Disconnect(int tmout, const ActDoneCB& cb) { MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer; Token* tok = nullptr; std::shared_ptr<Token> stok; if (cb) { tok = new Token(this); stok = std::shared_ptr<Token>(tok); stok->act_done_cb = cb; SaveToken(stok); } opts.onSuccess = cb?&Token::OnSuccess : nullptr ; opts.onFailure = cb?&Token::OnFailed : nullptr ; opts.timeout = tmout; opts.context = tok; int rc; if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS) { if (tok) RemoveToken(tok); throw rc; } return true; }
/* ParseVariableDecl - parse a variable declaration */ static int ParseVariableDecl(ParseContext *c, char *name, VMVALUE *pSize) { Token tkn; /* parse the variable name */ FRequire(c, T_IDENTIFIER); strcpy(name, c->token); /* handle arrays */ if ((tkn = GetToken(c)) == '[') { int size; /* check for an array with unspecified size */ if ((tkn = GetToken(c)) == ']') size = 0; /* otherwise, parse the array size */ else { ParseTreeNode *expr; /* put back the token */ SaveToken(c, tkn); /* get the array size */ expr = ParseExpr(c); /* make sure it's a constant */ if (!IsIntegerLit(expr) || expr->u.integerLit.value <= 0) ParseError(c, "expecting a positive constant expression"); size = expr->u.integerLit.value; /* only one dimension allowed for now */ FRequire(c, ']'); } /* return an array and its size */ *pSize = size; return VMTRUE; } /* not an array */ else SaveToken(c, tkn); /* return a scalar */ return VMFALSE; }
/* ParseDef - parse the 'DEF' statement */ static void ParseDef(ParseContext *c) { char name[MAXTOKEN]; Token tkn; /* get the name being defined */ FRequire(c, T_IDENTIFIER); strcpy(name, c->token); /* check for a constant definition */ if ((tkn = GetToken(c)) == '=') ParseConstantDef(c, name); /* otherwise, assume a function definition */ else { Symbol *sym; /* save the lookahead token */ SaveToken(c, tkn); /* enter the function name in the global symbol table */ sym = AddGlobal(c, name, SC_CONSTANT, 0, 0); /* start the code under construction */ StartCode(c, sym->name, CODE_TYPE_FUNCTION); sym->value = c->code; /* get the argument list */ if ((tkn = GetToken(c)) == '(') { if ((tkn = GetToken(c)) != ')') { int offset = 1; SaveToken(c, tkn); do { FRequire(c, T_IDENTIFIER); AddArgument(c, c->token, SC_VARIABLE, offset); ++offset; } while ((tkn = GetToken(c)) == ','); } Require(c, tkn, ')'); } else SaveToken(c, tkn); } FRequire(c, T_EOL); }
/* ParseReturn - parse the 'RETURN' statement */ static void ParseReturn(ParseContext *c) { Token tkn; if ((tkn = GetToken(c)) == T_EOL) { putcbyte(c, OP_LIT); putcword(c, 0); } else { SaveToken(c, tkn); ParseRValue(c); FRequire(c, T_EOL); } putcbyte(c, OP_RETURN); }
/* ParseDim - parse the 'DIM' statement */ static void ParseDim(ParseContext *c) { char name[MAXTOKEN]; VMVALUE value, size; int isArray; Token tkn; /* parse variable declarations */ do { /* get variable name */ isArray = ParseVariableDecl(c, name, &size); /* add to the global symbol table if outside a function definition */ if (c->codeType == CODE_TYPE_MAIN) { /* check for initializers */ if ((tkn = GetToken(c)) == '=') { if (isArray) ParseArrayInitializers(c, size); else value = ParseScalarInitializer(c); } /* no initializers */ else { ClearArrayInitializers(c, size); SaveToken(c, tkn); } /* create a vector object for arrays */ value = isArray ? StoreVector(c, (VMVALUE *)c->codeBuf, size) : 0; /* add the symbol to the global symbol table */ AddGlobal(c, name, SC_VARIABLE, c->image->variableCount++, value); } /* otherwise, add to the local symbol table */ else { if (isArray) ParseError(c, "local arrays are not supported"); AddLocal(c, name, SC_VARIABLE, c->localOffset + F_SIZE + 1); ++c->localOffset; } } while ((tkn = GetToken(c)) == ','); Require(c, tkn, T_EOL); }
/* ParseExpr3 - handle the BXOR operator */ static ParseTreeNode *ParseExpr3(ParseContext *c) { ParseTreeNode *expr, *expr2; int tkn; expr = ParseExpr4(c); while ((tkn = GetToken(c)) == '^') { expr2 = ParseExpr4(c); if (IsIntegerLit(expr) && IsIntegerLit(expr2)) expr->u.integerLit.value = expr->u.integerLit.value ^ expr2->u.integerLit.value; else expr = MakeBinaryOpNode(c, OP_BXOR, expr, expr2); } SaveToken(c,tkn); return expr; }
/* ParseImpliedLetOrFunctionCall - parse an implied let statement or a function call */ static void ParseImpliedLetOrFunctionCall(ParseContext *c) { ParseTreeNode *expr; Token tkn; PVAL pv; expr = ParsePrimary(c); switch (tkn = GetToken(c)) { case '=': code_lvalue(c, expr, &pv); ParseRValue(c); (*pv.fcn)(c, PV_STORE, &pv); break; default: SaveToken(c, tkn); code_rvalue(c, expr); putcbyte(c, OP_DROP); break; } FRequire(c, T_EOL); }
bool mqtt_async::MqttClient::Connect(int interval, const ActDoneCB& cb) { int rc; if (!monitor_init) { MQTTAsync_connectionLost* cl = monitor.conn_lost_cb? &Monitor::ConnectionLost : nullptr; MQTTAsync_messageArrived* ma = monitor.msg_recv_cb? &Monitor::MsgRecv : nullptr; MQTTAsync_deliveryComplete* dc = monitor.delivery_done_cb ? &Monitor::Delivered : nullptr; rc = MQTTAsync_setCallbacks(client, &monitor, cl, ma, dc); if (rc != MQTTASYNC_SUCCESS) throw rc; monitor_init = true; } MQTTAsync_connectOptions opts = MQTTAsync_connectOptions_initializer; opts.keepAliveInterval = interval; opts.cleansession = 1; Token* tok = nullptr; std::shared_ptr<Token> stok; if (cb) { tok = new Token(this); stok = std::shared_ptr<Token>(tok); stok->act_done_cb = cb; SaveToken(stok); } opts.onSuccess = cb?&Token::OnSuccess : nullptr ; opts.onFailure = cb?&Token::OnFailed : nullptr ; opts.context = tok; if ((rc = MQTTAsync_connect(client, &opts)) != MQTTASYNC_SUCCESS) { if (tok) RemoveToken(tok); throw rc; } return true; }
/* ParsePrint - handle the 'PRINT' statement */ static void ParsePrint(ParseContext *c) { int needNewline = VMTRUE; ParseTreeNode *expr; Token tkn; while ((tkn = GetToken(c)) != T_EOL) { switch (tkn) { case ',': needNewline = VMFALSE; CallHandler(c, "printTab", NULL); break; case ';': needNewline = VMFALSE; break; default: needNewline = VMTRUE; SaveToken(c, tkn); expr = ParseExpr(c); switch (expr->nodeType) { case NodeTypeStringLit: CallHandler(c, "printStr", expr); break; default: CallHandler(c, "printInt", expr); break; } break; } } if (needNewline) CallHandler(c, "printNL", NULL); else CallHandler(c, "printFlush", NULL); }
/* ParseExpr2 - handle the AND operator */ static ParseTreeNode *ParseExpr2(ParseContext *c) { ParseTreeNode *node; int tkn; node = ParseExpr3(c); if ((tkn = GetToken(c)) == T_AND) { ParseTreeNode *node2 = NewParseTreeNode(c, NodeTypeConjunction); ExprListEntry *entry, **pLast; node2->u.exprList.exprs = entry = (ExprListEntry *)LocalAllocBasic(c, sizeof(ExprListEntry)); entry->expr = node; entry->next = NULL; pLast = &entry->next; do { entry = (ExprListEntry *)LocalAllocBasic(c, sizeof(ExprListEntry)); entry->expr = ParseExpr2(c); entry->next = NULL; *pLast = entry; pLast = &entry->next; } while ((tkn = GetToken(c)) == T_AND); node = node2; } SaveToken(c, tkn); return node; }
/* ParseStatement - parse a statement */ void ParseStatement(ParseContext *c, Token tkn) { /* dispatch on the statement keyword */ switch (tkn) { case T_REM: /* just a comment so ignore the rest of the line */ break; case T_DEF: ParseDef(c); break; case T_END_DEF: ParseEndDef(c); break; case T_DIM: ParseDim(c); break; case T_LET: ParseLet(c); break; case T_IF: ParseIf(c); break; case T_ELSE: ParseElse(c); break; case T_ELSE_IF: ParseElseIf(c); break; case T_END_IF: ParseEndIf(c); break; case T_END: ParseEnd(c); break; case T_FOR: ParseFor(c); break; case T_NEXT: ParseNext(c); break; case T_DO: ParseDo(c); break; case T_DO_WHILE: ParseDoWhile(c); break; case T_DO_UNTIL: ParseDoUntil(c); break; case T_LOOP: ParseLoop(c); break; case T_LOOP_WHILE: ParseLoopWhile(c); break; case T_LOOP_UNTIL: ParseLoopUntil(c); break; case T_STOP: ParseStop(c); break; case T_GOTO: ParseGoto(c); break; case T_RETURN: ParseReturn(c); break; case T_PRINT: ParsePrint(c); break; case T_IDENTIFIER: if (SkipSpaces(c) == ':') { DefineLabel(c, c->token, codeaddr(c)); break; } UngetC(c); default: SaveToken(c, tkn); ParseImpliedLetOrFunctionCall(c); break; } }