Node<FunctionNode>::Link FunctionParser::function(bool isForeign) { if (isForeign) skip(); // Skip "foreign" Trace trace = current().trace; skip(); // Skip "function" or "method" std::string ident = ""; FunctionSignature::Arguments args {}; std::unique_ptr<TypeInfo> returnType; // Is not anon func if (accept(TT::IDENTIFIER)) { ident = current().data; skip(); } if (isForeign && ident.empty()) throw Error("SyntaxError", "Foreign functions can't be anonymous", trace); // Has arguments if (accept(TT::SQPAREN_LEFT)) { skip(); args = getSigArgs(); } // Has return type if (accept(TT::FAT_ARROW)) { skip(); returnType = std::make_unique<TypeInfo>(getTypeList()); } auto func = Node<FunctionNode>::make(ident, FunctionSignature(returnType == nullptr ? nullptr : *returnType, args), isForeign); func->setTrace(trace); // Only non-foreign functions have code bodies if (!isForeign) func->setCode(block(FUNCTION_BLOCK)); // Foreign declarations end in semicolon if (isForeign) expectSemi(); return func; }
static BOOLEAN is_polymorphic(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp) { INITLIST *lst; BOOLEAN rv = FALSE; FUNCTIONCALL funcparams; memset(&funcparams, 0, sizeof(funcparams)); funcparams.sp = sym; *lex = getTypeList(*lex, funcsp, &funcparams.arguments); lst = funcparams.arguments; while (lst) { lst->tp = PerformDeferredInitialization(lst->tp, NULL); lst = lst->next; } if (funcparams.arguments && !funcparams.arguments-> next) { // yes references are literal types... if (isstructured(funcparams.arguments->tp)) rv = !! hasVTab(basetype(funcparams.arguments->tp)->sp); } *exp = intNode(en_c_i, rv); *tp = &stdint; return TRUE; }
QString BarCode::getTypeName(BarcodeTypes type) { BarcodeTypePairList list = getTypeList(); for (int i=0; i < list.size(); i++) { if (list.at(i).first == type) return list.at(i).second; } return QString(); }
QList<QString>* GRIProcList::retrieveList(QString procName, QString list) { process* proc = process_map_.value(procName); if (proc != NULL) { return getTypeList(proc, list); } return new QList<QString>(); }
Node<TypeNode>::Link TypeParser::type() { skip(); // Skip "type" expect(TT::IDENTIFIER, "Expected identifier after 'type' token"); Node<TypeNode>::Link tn; Token identTok = current(); skip(); if (accept(TT::INHERITS)) { skip(); if (accept(TT::FROM)) skip(); // Having "from" after "inherits" is optional tn = Node<TypeNode>::make(identTok.data, getTypeList()); } else { tn = Node<TypeNode>::make(identTok.data); } tn->setTrace(identTok.trace); expect(TT::DO, "Expected type body"); skip(); while (!accept(TT::END)) { if (accept(TT::FILE_END)) { skip(-1); // Go back to get a prettier trace throw Error("SyntaxError", "Type body is not closed by 'end'", current().trace); } bool isStatic = false; bool isForeign = false; Visibility visibility = INVALID; // Expect to see a visibility_specifier or static or foreign while (accept(TT::PUBLIC) || accept(TT::PRIVATE) || accept(TT::PROTECT) || accept(TT::STATIC) || accept(TT::FOREIGN)) { if (accept(TT::STATIC)) { if (isStatic == true) throw Error("SyntaxError", "Cannot specify 'static' more than once", current().trace); isStatic = true; } else if (accept(TT::FOREIGN)) { if (isForeign == true) throw Error("SyntaxError", "Cannot specify 'foreign' more than once", current().trace); isForeign = true; } else { if (visibility != INVALID) throw Error("SyntaxError", "Cannot have more than one visibility specifier", current().trace); visibility = fromToken(current()); } skip(); } // Handle things that go in the body if (accept(TT::CONSTR)) { if (isStatic) throw Error("SyntaxError", "Constructors can't be static", current().trace); tn->addChild(constructor(visibility, isForeign)); } else if (accept(TT::METHOD)) { if (visibility == INVALID) throw Error("SyntaxError", "Methods require a visibility specifier", current().trace); tn->addChild(method(visibility, isStatic, isForeign)); } else { if (isForeign) throw Error("SyntaxError", "Member fields can't be foreign", current().trace); tn->addChild(member(visibility, isStatic)); expectSemi(); } } return tn; }
int GRIProcList::deleteType(QString procName, QString type, QString value) { process* proc = process_map_.value(procName); if (proc == 0) { return -1; } else { QList<QString>* typeList = getTypeList(proc, type); if (typeList == NULL) { return -1; } else if ((*typeList).removeOne(value)) { return 1; } else { return 0; } } }
static BOOLEAN is_union(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp) { INITLIST *lst; BOOLEAN rv = FALSE; FUNCTIONCALL funcparams; memset(&funcparams, 0, sizeof(funcparams)); funcparams.sp = sym; *lex = getTypeList(*lex, funcsp, &funcparams.arguments); if (funcparams.arguments && !funcparams.arguments-> next) { rv = basetype(funcparams.arguments->tp)->type == bt_union; } *exp = intNode(en_c_i, rv); *tp = &stdint; return TRUE; }
static BOOLEAN is_literal(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp) { INITLIST *lst; BOOLEAN rv = FALSE; FUNCTIONCALL funcparams; memset(&funcparams, 0, sizeof(funcparams)); funcparams.sp = sym; *lex = getTypeList(*lex, funcsp, &funcparams.arguments); if (funcparams.arguments && !funcparams.arguments-> next) { // yes references are literal types... rv = !isstructured(funcparams.arguments->tp); } *exp = intNode(en_c_i, rv); *tp = &stdint; return TRUE; }
FunctionSignature::Arguments FunctionParser::getSigArgs() { FunctionSignature::Arguments args; while (true) { expect(TT::IDENTIFIER, "Expected identifier in function arguments"); TypeList tl = getTypeList(); args.push_back(std::make_pair(current().data, tl)); skip(); // Skip the argument name if (accept(TT::SQPAREN_RIGHT)) { skip(); break; } if (!accept(",")) { throw Error("SyntaxError", "Expected comma after function argument", current().trace); } skip(); // The comma } return args; }
int GRIProcList::insertType(QString procName, QString type, QString value) { process* proc = process_map_.value(procName); if (proc == NULL) { process* newproc = new process(); proc = newproc; process_map_.insert(procName, proc); } QList<QString>* typeList = getTypeList(proc, type); if (typeList == NULL) { return -1; } else if ((*typeList).contains(value)) { return 0; } else { (*typeList).append(value); return 1; } }
static BOOLEAN is_trivially_constructible(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp) { INITLIST *lst; BOOLEAN rv = FALSE; FUNCTIONCALL funcparams; memset(&funcparams, 0, sizeof(funcparams)); funcparams.sp = sym; *lex = getTypeList(*lex, funcsp, &funcparams.arguments); lst = funcparams.arguments; while (lst) { lst->tp = PerformDeferredInitialization(lst->tp, NULL); lst = lst->next; } if (funcparams.arguments && !funcparams.arguments-> next) { rv = trivialCopyConstructible(funcparams.arguments->tp) && trivialDefaultConstructor(funcparams.arguments->tp); } *exp = intNode(en_c_i, rv); *tp = &stdint; return TRUE; }
static BOOLEAN is_standard_layout(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp) { INITLIST *lst; BOOLEAN rv = FALSE; FUNCTIONCALL funcparams; memset(&funcparams, 0, sizeof(funcparams)); funcparams.sp = sym; *lex = getTypeList(*lex, funcsp, &funcparams.arguments); lst = funcparams.arguments; while (lst) { lst->tp = PerformDeferredInitialization(lst->tp, NULL); lst = lst->next; } if (funcparams.arguments && !funcparams.arguments-> next) { rv = !!isStandardLayout(funcparams.arguments->tp, NULL); } *exp = intNode(en_c_i, rv); *tp = &stdint; return TRUE; }
static BOOLEAN is_empty(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp) { INITLIST *lst; BOOLEAN rv = FALSE; FUNCTIONCALL funcparams; memset(&funcparams, 0, sizeof(funcparams)); funcparams.sp = sym; *lex = getTypeList(*lex, funcsp, &funcparams.arguments); lst = funcparams.arguments; while (lst) { lst->tp = PerformDeferredInitialization(lst->tp, NULL); lst = lst->next; } if (funcparams.arguments && !funcparams.arguments-> next) { if (isstructured(funcparams.arguments->tp)) rv = !basetype(funcparams.arguments->tp)->syms->table[0] || !basetype(funcparams.arguments->tp)->syms->table[0]->next; } *exp = intNode(en_c_i, rv); *tp = &stdint; return TRUE; }
static BOOLEAN is_convertible_to(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp) { BOOLEAN rv = TRUE; FUNCTIONCALL funcparams; memset(&funcparams, 0, sizeof(funcparams)); funcparams.sp = sym; *lex = getTypeList(*lex, funcsp, &funcparams.arguments); if (funcparams.arguments && funcparams.arguments->next && !funcparams.arguments->next->next) { TYPE *from = funcparams.arguments->tp; TYPE *to = funcparams.arguments->next->tp; if (isref(from) && isref(to)) { if (basetype(to)->type == bt_lref) { if (basetype(from)->type == bt_rref) rv = FALSE; } } else if (isref(from)) rv = FALSE; if (isfunction(from)) from = basetype(from)->btp; if (rv) { while (isref(from)) from = basetype(from)->btp; while (isref(to)) to = basetype(to)->btp; rv = comparetypes(to, from, FALSE); if (!rv && isstructured(from) && isstructured(to)) { if (classRefCount(basetype(to)->sp, basetype(from)->sp) == 1) rv = TRUE; } if (!rv && isstructured(from)) { SYMBOL *sp = search("$bcall", basetype(from)->syms); if (sp) { HASHREC *hr = sp->tp->syms->table[0]; while (hr) { if (comparetypes(basetype(((SYMBOL *)hr->p)->tp)->btp, to, FALSE)) { rv= TRUE; break; } hr = hr->next; } } } } } else { rv = FALSE; } *exp = intNode(en_c_i, rv); *tp = &stdint; return TRUE; }
static BOOLEAN is_constructible(LEXEME **lex, SYMBOL *funcsp, SYMBOL *sym, TYPE **tp, EXPRESSION **exp) { INITLIST *lst; BOOLEAN rv = FALSE; FUNCTIONCALL funcparams; memset(&funcparams, 0, sizeof(funcparams)); funcparams.sp = sym; *lex = getTypeList(*lex, funcsp, &funcparams.arguments); lst = funcparams.arguments; while (lst) { lst->tp = PerformDeferredInitialization(lst->tp, NULL); lst = lst->next; } if (funcparams.arguments) { TYPE *tp2 = funcparams.arguments->tp; if (isarray(tp2)) { while (isarray(tp2) && tp2->size != 0) tp2 = tp2->btp; if (isarray(tp2)) { tp2 = FALSE; } } if (tp2) { if (isarithmetic(tp2) || ispointer(tp2) || basetype(tp2)->type == bt_enum) { if (!funcparams.arguments->next) { rv = TRUE; } else if (!funcparams.arguments->next->next) { rv = comparetypes(tp2, funcparams.arguments->next->tp, TRUE); } } else if (isref(tp2)) { if (funcparams.arguments->next && !funcparams.arguments->next->next) { rv = comparetypes(tp2, funcparams.arguments->next->tp, TRUE); } } else if (isstructured(tp2)) { TYPE *ctp = tp2; EXPRESSION *cexp = NULL; SYMBOL *cons = search(overloadNameTab[CI_CONSTRUCTOR], basetype(tp2)->syms); funcparams.thisptr = intNode(en_c_i, 0); funcparams.thistp = Alloc(sizeof(TYPE)); funcparams.thistp->type = bt_pointer; funcparams.thistp->btp = basetype(tp2); funcparams.thistp->size = getSize(bt_pointer); funcparams.ascall = TRUE; funcparams.arguments = funcparams.arguments->next; rv = GetOverloadedFunction(tp, &funcparams.fcall, cons, &funcparams, NULL, FALSE, FALSE, FALSE, _F_SIZEOF) != NULL; } } } *exp = intNode(en_c_i, rv); *tp = &stdint; return TRUE; }