int main(int argc, char **argv) { FILE *input = fopen(argv[1], "r"); int name_counter = 0, words = 0; char buffer[MAX_LINE], *token, delim[] = " ,\t"; char name[MAX_LINE]; if (input == NULL){ return -1; } while(fgets(buffer, MAX_LINE, input)){ if (buffer[strlen(buffer) - 1] == '\n'){ buffer[strlen(buffer) - 1] = '\0'; } token = strtok(buffer, delim); while( token != NULL ){ //printf("%s\n", token); if (isDate(token) == 1){ printf("Found a date: %s\n", token ); } if (isPhoneNumber(token)){ printf("Found a phone number: %s\n", token ); } if (name_counter == 1 && isName(token) == 0){ name_counter = 0; } if (isName(token)){ name_counter++; if (name_counter == 2){ printf("Name found: %s %s\n", name, token ); name_counter = 0; } else { strcpy(name, token); } } if (isEmail(token)){ printf("Found an email: %s\n", token ); } token = strtok(NULL, delim); words++; } } printf("There are %d words in the file\n", words ); }
Token *Lexer::nextToken() { while(true) { switch(_currentChar.toAscii()) { case '\'': return scanCharacter(); case '"': return scanText(); case '(': return scan(Token::LeftParenthesis); case ')': return scan(Token::RightParenthesis); case '[': return scan(Token::LeftBracket); case ']': return scanRightBracket(); case '{': return scan(Token::LeftBrace); case '}': return scan(Token::RightBrace); case ';': return scan(Token::Semicolon); default: if(isEof()) return scan(Token::Eof); else if(isLineComment()) consumeLineComment(); else if(isBlockComment()) consumeBlockComment(); else if(isNewline()) return scanNewline(); else if(isSpace()) consumeSpaces(); else if(isName()) return scanName(); else if(isBackquotedName()) return scanBackquotedName(); else if(isNumber()) return scanNumber(); else if(isOperator()) return scanOperator(); else throw lexerException(QString("invalid character: '%1'").arg(_currentChar)); } } }
static int endOfKeyword(const char *name, int first) { int next = first; while (isName(name[next + 1])) ++next; return next; }
char * pcePPReference(PceObject ref) { if ( isInteger(ref) ) { Any addr = longToPointer(valInt(ref)); char *rval = pp(addr); if ( rval[0] != '@' ) { char tmp[256]; sprintf(tmp, "@" INTPTR_FORMAT, valInt(ref)); return save_string(tmp); } else return rval; } else if ( isName(ref) ) { Any addr; if ( !(addr = getObjectAssoc(ref)) ) { char tmp[256]; sprintf(tmp, "@%s", strName(ref)); return save_string(tmp); } else return pp(addr); } else return save_string("invalid reference"); }
bool Menu::choicePlayers(Game &game) { bool back; back = false; game.soundMain(); std::cout << "la" << std::endl; while (game.play() && back == false) { back = false; game.initScene(); isName(true); switch (drawPlayMenu()) { case Click::ONE: back = lunchGame(1, game); break; case Click::TWO: back = lunchGame(2, game); break; case Click::THREE: back = lunchGame(3, game); break; case Click::IA: back = lunchGame(0, game); break; case Click::CANCEL: back = true; break ; default: break ; } game.endScene(); } return back; }
static void ws_open_colourmap(ColourMap cm) { if ( !getExistingPaletteColourMap(cm) && notNil(cm->colours) ) { int size = valInt(cm->colours->size); LOGPALETTE *lp = pceMalloc(offset(LOGPALETTE, palPalEntry[size])); PALETTEENTRY *pe = &lp->palPalEntry[0]; HPALETTE hpal; int n, nc = 0; DisplayObj d = CurrentDisplay(NIL); for(n=0; n<size; n++) { Colour c = cm->colours->elements[n]; if ( isName(c) && (c = checkType(c, TypeColour, NIL)) ) elementVector(cm->colours, toInt(n+1), c); if ( instanceOfObject(c, ClassColour) ) { if ( c->kind == NAME_named ) ws_create_colour(c, d); pe->peRed = valInt(c->red) >> 8; pe->peGreen = valInt(c->green) >> 8; pe->peBlue = valInt(c->blue) >> 8; pe->peFlags = 0; pe++; nc++; } else Cprintf("%s is not a colour\n", pp(c)); }
static bool hasDefCycle ( const TConcept* C, ConceptSet& visited ) { // interested in non-primitive if ( C->isPrimitive() ) return false; // already seen -- cycle if ( visited.count(C) > 0 ) return true; // check the structure: looking for the \exists R.C const DLTree* p = C->Description; if ( p->Element().getToken() != NOT ) return false; p = p->Left(); if ( p->Element().getToken() != FORALL ) return false; p = p->Right(); if ( p->Element().getToken() != NOT ) return false; p = p->Left(); if ( !isName(p) ) return false; // here P is a concept // remember C visited.insert(C); // check p return hasDefCycle ( static_cast<const TConcept*>(p->Element().getNE()), visited ); }
static Elevation getLookupElevation(Any receiver, Any name, Int height, Any colour, Any relief, Any shadow, Name kind, Any bg) { Elevation e = getMemberHashTable(ElevationTable, name); if ( e && isName(name) && (isDefault(height) || height == e->height) && (isDefault(colour) || colour == e->colour) && (isDefault(bg) || bg == e->background) && (isDefault(relief) || relief == e->relief) && (isDefault(shadow) || shadow == e->shadow) && (isDefault(kind) || kind == e->kind) ) answer(e); if ( e && isInteger(name) && isDefault(height) && isDefault(colour) && isDefault(bg) && isDefault(relief) && isDefault(shadow) && isDefault(kind) ) answer(e); fail; }
temp<Token> Lexer::readName() { // TODO(bob): Handle EOF. while (isName(peek())) advance(); temp<String> text = source_->substring(start_, pos_); // See if it's a reserved word. TokenType type = TOKEN_NAME; if (*text == "and" ) type = TOKEN_AND; else if (*text == "case" ) type = TOKEN_CASE; else if (*text == "def" ) type = TOKEN_DEF; else if (*text == "do" ) type = TOKEN_DO; else if (*text == "else" ) type = TOKEN_ELSE; else if (*text == "end" ) type = TOKEN_END; else if (*text == "false" ) type = TOKEN_FALSE; else if (*text == "for" ) type = TOKEN_FOR; else if (*text == "if" ) type = TOKEN_IF; else if (*text == "is" ) type = TOKEN_IS; else if (*text == "match" ) type = TOKEN_MATCH; else if (*text == "not" ) type = TOKEN_NOT; else if (*text == "or" ) type = TOKEN_OR; else if (*text == "return") type = TOKEN_RETURN; else if (*text == "then" ) type = TOKEN_THEN; else if (*text == "true" ) type = TOKEN_TRUE; else if (*text == "val" ) type = TOKEN_VAL; else if (*text == "var" ) type = TOKEN_VAR; else if (*text == "while" ) type = TOKEN_WHILE; else if (*text == "xor" ) type = TOKEN_XOR; return Token::create(type, text); }
void Parser::matchName() { if (isName()) { getToken(); } else { throw ParseException(_stmtNum, _token, "Name should contains only letters & digits with a letter as beginning"); } }
bool Token::isUpperCaseName() const { if (!isName()) return false; for (size_t i = 0; i < _str.length(); ++i) { if (std::islower(_str[i])) return false; } return true; }
//returns true if tag closes itself (<tag/>); false if not (<tag>) inline bool parseHead(const char *&p) { //parse name const char *nameStart = ++p; //skip '<' while(isName(*p)) p++; const char *nameEnd = p; copy(name, nameStart, nameEnd - nameStart); if(name.empty()) throw "missing element name"; //parse attributes while(*p) { while(isWhitespace(*p)) p++; if(!*p) throw "unclosed attribute"; if(*p == '?' || *p == '/' || *p == '>') break; //parse attribute name Node *attribute = new Node; children.append(attribute); attribute->attribute = true; const char *nameStart = p; while(isName(*p)) p++; const char *nameEnd = p; copy(attribute->name, nameStart, nameEnd - nameStart); if(attribute->name.empty()) throw "missing attribute name"; //parse attribute data if(*p++ != '=') throw "missing attribute value"; char terminal = *p++; if(terminal != '\'' && terminal != '\"') throw "attribute value not quoted"; const char *dataStart = p; while(*p && *p != terminal) p++; if(!*p) throw "missing attribute data terminal"; const char *dataEnd = p++; //skip closing terminal copy(attribute->data, dataStart, dataEnd - dataStart); } //parse closure if(*p == '?' && *(p + 1) == '>') { p += 2; return true; } if(*p == '/' && *(p + 1) == '>') { p += 2; return true; } if(*p == '>') { p += 1; return false; } throw "invalid element tag"; }
static void readName(Lexer *l) { while (isName(l) || isDigit(peek(l))) next(l); TokenType type = TOKEN_NAME; if(isKeyword(l, "let")) type = TOKEN_LET; addToken(l, type); }
Token *Lexer::scanNumber() { startToken(); consume(); short base = 10; bool decimalPointFound = false; bool eFound = false; bool oneMoreDigitExpected = false; if(_previousChar == '0') { if(_currentChar == 'x' || _currentChar == 'X') { base = 16; consume(); oneMoreDigitExpected = true; } else if(_currentChar.isNumber()) { base = 8; oneMoreDigitExpected = true; } else if(_currentChar == 'b' || _currentChar == 'B') { base = 2; consume(); oneMoreDigitExpected = true; } } while(true) { if(_currentChar.isNumber()) { if(base == 2 && !(_currentChar == '0' || _currentChar == '1')) throw lexerException("a binary number can only contain 0 or 1"); if(base == 8 && !QString("01234567").contains(_currentChar)) throw lexerException("an octal number can only contain digits from 0 to 7"); oneMoreDigitExpected = false; } else if(base == 16 && QString("abcdef").contains(_currentChar, Qt::CaseInsensitive)) { oneMoreDigitExpected = false; } else if(_currentChar == '.' && _nextChar.isNumber()) { if(decimalPointFound) throw lexerException("too many decimal points in a number"); if(eFound) throw lexerException("the exponential part of a number cannot contain a decimal point"); if(base == 16) throw lexerException("an hexadecimal number cannot contain a decimal point"); if(base == 8) throw lexerException("an octal number cannot contain a decimal point"); if(base == 2) throw lexerException("a binary number cannot contain a decimal point"); decimalPointFound = true; oneMoreDigitExpected = true; } else if(base != 16 && (_currentChar == 'e' || _currentChar == 'E')) { if(eFound) throw lexerException("a number cannot contain more than one exponential part"); if(base == 8) throw lexerException("an octal number cannot contain an exponential part"); if(base == 2) throw lexerException("a binary number cannot contain an exponential part"); eFound = true; oneMoreDigitExpected = true; } else if((_currentChar == '+' || _currentChar == '-') && base == 10 && (_previousChar == 'e' || _previousChar == 'E')) { // All is good in the hood! } else if(isName()) { throw lexerException(QString("unexpected character found in a number: '%1'").arg(_currentChar)); } else break; consume(); } if(oneMoreDigitExpected) throw lexerException(QString("unexpected character found in a number: '%1'").arg(_currentChar)); return finishToken(Token::Number); }
void ASTExpressionBuilder::buildOperands() { ASTType type; if (isDigits()) { type = CONSTANT; } else if (isName()) { type = VARIABLE; } _results.push_back(new ASTNode(_token, type, 0)); }
int accelerator_code(Name a) { if ( isName(a) ) { char *s = strName(a); if ( s[0] == '\\' && s[1] == 'e' && isalpha(s[2]) && s[3] == EOS ) return s[2]; if ( s[1] == EOS && isalpha(s[0]) ) return s[0]; } return 0; }
Token *tokenize(Buffer *input) { Lexer *l; l->source = input; l->start = 0; l->pos = 0; l->head = NULL; l->tail = NULL; while (peek(l) != '\0') { l->start = l->pos; char c = next(l); switch(c) { case '(': addToken(l, TOKEN_LEFT_PAREN); break; case ')': addToken(l, TOKEN_RIGHT_PAREN); break; case '%': addToken(l, TOKEN_MOD); break; case '.': addToken(l, TOKEN_DOT); break; case '/': addToken(l, TOKEN_SLASH); break; case '*': addToken(l, TOKEN_STAR); break; case '=': addToken(l, TOKEN_EQ); break; case '-': addToken(l, TOKEN_MINUS); break; case '+': addToken(l, TOKEN_PLUS); break; case ' ': readWhitespace(l); break; case '"': readString(l); break; case '\n': addToken(l, TOKEN_LINE); break; default: if (isName(c)) { readName(l); } else if (isDigit(c)) { readNumber(c); } else { emitToken(l, TOKEN_ERROR); } break; } } lexer.start = lexer.pos; emitToken(l, TOKEN_EOF); return l->head; }
static status initialiseDictItem(DictItem di, Any key, CharArray lbl, Any obj, Name style) { if ( instanceOfObject(key, ClassCharArray) && !isName(key) ) key = toName(key); assign(di, key, key); assign(di, label, lbl); assign(di, index, ZERO); assign(di, object, (isDefault(obj) ? NIL : obj)); assign(di, dict, NIL); assign(di, style, style); succeed; }
ASTNode* ASTExpressionBuilder::shuntingYardAlgorithm() { _operators.clear(); _results.clear(); while (!_tokens.empty()) { _token = _tokens.front(); _tokens.pop_front(); if (isKeyword("+") || isKeyword("-") || isKeyword("*") || isKeyword("/")) { while (!_operators.empty() && getOprPriority(_token) <= getOprPriority(_operators.back())) { buildOperators(); } _operators.push_back(_token); } else if (isKeyword("(")) { _operators.push_back("("); } else if (isKeyword(")")) { while (!_operators.empty() && _operators.back() != "(") { buildOperators(); } if (_operators.empty()) { throw ParseException(_token, "Mismatched parentheses"); } _operators.pop_back(); } else if (isDigits() || isName()) { buildOperands(); } else { throw ParseException(_token, "Unable to parse expression"); } getToken(); } while (!_operators.empty()) { if (_operators.back() == "(") { throw ParseException(_token, "Mismatched parentheses"); } buildOperators(); } ASTNode* expNode = _results.back(); _results.pop_back(); return expNode; }
/// absorb into negation of a concept; @return true if absorption is performed bool TAxiom :: absorbIntoNegConcept ( TBox& KB ) const { WorkSet Cons; TConcept* Concept; const DLTree* bestConcept = NULL; // finds all primitive negated concept names without description for ( const_iterator p = begin(), p_end = end(); p != p_end; ++p ) if ( (*p)->Element().getToken() == NOT && isName((*p)->Left()) && (Concept = InAx::getConcept((*p)->Left()))->isPrimitive() && !Concept->isSingleton() && Concept->Description == NULL ) { Stat::SAbsNAttempt(); Cons.push_back(*p); } // if no concept names -- return; if ( Cons.empty() ) return false; Stat::SAbsNApply(); // FIXME!! as for now: just take the 1st concept name if ( bestConcept == NULL ) bestConcept = Cons[0]; // normal concept absorption Concept = InAx::getConcept(bestConcept->Left()); #ifdef RKG_DEBUG_ABSORPTION std::cout << " N-Absorb GCI to concept " << Concept->getName(); if ( Cons.size() > 1 ) { std::cout << " (other options are"; for ( WorkSet::iterator q = Cons.begin(), q_end = Cons.end(); q != q_end; ++q ) if ( *q != bestConcept ) std::cout << " " << InAx::getConcept((*q)->Left())->getName(); std::cout << ")"; } #endif // replace ~C [= D with C=~notC, notC [= D: // make notC [= D TConcept* nC = KB.getAuxConcept(createAnAxiom(bestConcept)); // define C = ~notC; C had an empty desc, so it's safe not to delete it KB.makeNonPrimitive ( Concept, createSNFNot(KB.getTree(nC)) ); return true; }
static BOOL CALLBACK next_monitor(HMONITOR m, HDC hdc, LPRECT rect, LPARAM closure) { DisplayObj d = (DisplayObj)closure; MONITORINFOEX info; Any name; Monitor mon; memset(&info, 0, sizeof(info)); info.cbSize = sizeof(info); if ( GetMonitorInfo(m, (MONITORINFO*)&info) ) { name = CtoName(info.szDevice); } else { name = d->monitors->size; } appendChain(d->monitors, mon=newObject(ClassMonitor, name, newObject(ClassArea, toInt(rect->left), toInt(rect->top), toInt(rect->right - rect->left), toInt(rect->bottom - rect->top), EAV), EAV)); if ( isName(name) ) { if ( info.dwFlags & MONITORINFOF_PRIMARY ) assign(mon, primary, ON); assign(mon, work_area, newObject(ClassArea, toInt(info.rcWork.left), toInt(info.rcWork.top), toInt(info.rcWork.right - info.rcWork.left), toInt(info.rcWork.bottom - info.rcWork.top), EAV)); } return TRUE; }
ASTNode* Parser::statement() { _stmtNum++; if (isKeyword("while")) { return whileStmt(); } if (isKeyword("if")) { return ifStmt(); } if (isKeyword("call")) { return callStmt(); } if (isName()) { return assignStmt(); } throw ParseException(_stmtNum, _token, "Unable to parse statement"); }
void Token::print() const { if( eol() ) std::cout << "NEWLINE" ; else if( eof() ) std::cout << "ENDMARKER" ; else if( indent() ) std::cout << "INDENT"; else if( dedent() ) std::cout << "DEDENT"; else if( isOpenBrace() ) std::cout << " { "; else if( isCloseBrace() ) std::cout << " } "; else if( isComma() ) std::cout << " , "; else if( isPeriod()) std::cout<< "."; else if( isEqual() ) std::cout << " == "; else if( isNotEqual() ) std::cout << " != "; else if( isLessThan() ) std::cout << " < "; else if( isGreaterThan() ) std::cout << " > "; else if( isLessThanEqual() ) std::cout << " <= "; else if( isGreaterThanEqual() ) std::cout << " >= "; else if( isOpenParen() ) std::cout << " ( " ; else if( isCloseParen() ) std::cout << " ) " ; else if( isAssignmentOperator() ) std::cout << " = "; else if( isColon() ) std::cout << " : " ; else if( isMultiplicationOperator() ) std::cout << " * " ; else if( isAdditionOperator() ) std::cout << " + "; else if( isSubtractionOperator() ) std::cout << " - "; else if( isModuloOperator() ) std::cout << " % "; else if( isDivisionOperator() ) std::cout << " / "; else if( isFloorDivision() ) std::cout << " // "; else if( isOpenBrack() ) std::cout<< "["; else if( isCloseBrack() ) std::cout<< "]"; else if( isName() ) std::cout << getName(); else if( isKeyword() ) std::cout << getKeyword(); else if( isWholeNumber() ) std::cout << getWholeNumber(); else if( isFloat() ) std::cout << getFloat(); else if( isString() ) std::cout << getString(); else if( isCall() ) std::cout << "CALL " << getName(); else if( isSub() ) std::cout << "ARRAY SUB " << getName(); else if( isAppend() ) std::cout << "ARRAY APPEND " << getName(); else if( isPop() ) std::cout << "ARRAY POP " << getName(); else std::cout << "Uninitialized token.\n"; }
QColor GeneralConfig::getColorFromString(QString colorString) { /* -converts a color defined in a string to a 'QColor' object, using regexp validation, and returnes it */ if ( colorString.isEmpty() ) return QColor(); //return if no color is specified //cleen up the string colorString = colorString.simplified(); colorString = colorString.trimmed(); QColor returnColor(0, 0, 0); //dummy color to be returned int p = 0; //used for regexp validator //regexps to check color value QRegularExpressionValidator isRGB( QRegularExpression("\\d{1,3} \\d{1,3} \\d{1,3}") ); //check if RGB QRegularExpressionValidator isRGBA( QRegularExpression("\\d{1,3} \\d{1,3} \\d{1,3} \\d{1,3}") ); //check if RGBA QRegularExpressionValidator isHEX( QRegularExpression("^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8}|[0-9A-Fa-f]{9}|[0-9A-Fa-f]{12})$") );//check if HEX code QRegularExpressionValidator isName( QRegularExpression("\\w+") ); //check if color name //check color value if ( isRGB.validate(colorString, p) == 2) { QStringList rgb = colorString.split( QRegularExpression("\\s") ); returnColor.setRgb( rgb.at(0).toInt(), rgb.at(1).toInt(), rgb.at(2).toInt() ); } else if ( isRGBA.validate(colorString, p) == 2) { QStringList rgb = colorString.split( QRegularExpression("\\s") ); returnColor.setRgb( rgb.at(0).toInt(), rgb.at(1).toInt(), rgb.at(2).toInt(), rgb.at(3).toInt() ); } else if ( isHEX.validate(colorString, p) == 2) { returnColor.setNamedColor(colorString); } else if ( isName.validate(colorString, p) ) { returnColor.setNamedColor( colorString.toLower().remove( QRegularExpression("\\s+") ) ); } //check color is valid and return if ( returnColor.isValid() ) return returnColor; else return QColor(); }
std::list<std::string> Parser::getExpressionTokens() { std::list<std::string> tokens; while (!isKeyword(";")) { if (isKeyword("(") || isKeyword(")") || isKeyword("+") || isKeyword("-") || isKeyword("*") || isKeyword("/")) { tokens.push_back(_token); } else if (isDigits()) { _constTable->addConstant(std::stoi(_token)); tokens.push_back(_token); } else if (isName()) { _varTable->addVariable(_token); tokens.push_back(_token); } else { throw ParseException(_stmtNum, _token, "Unable to parse expression"); } getToken(); } return tokens; }
// Statements bool isSimpleStatement() const { return isPrintKeyword() || isName() || isArrayOp() || isCall() || isReturnKeyword(); }
refObject skolemize(refObject layer, refObject type) { struct { refFrame link; int count; refObject first; refObject labeler; refObject last; refObject layer; refObject next; refObject type; } f0; // IS SKOLEMIZABLE. Test if TYPE, which is ground in LAYER, can be the base of // a Skolem type. It can be, if it has a subtype that's different from itself. // For example, OBJ has an infinite number of such subtypes but INT0 has none. // The WHILE loop helps simulate tail recursions. bool isSkolemizable(refObject layer, refObject type) { while (true) { if (isName(type)) { getKey(r(layer), r(type), layer, type); } else // Visit a type. If LABELER says we've been here before, then return false. If // we haven't, then record TYPE in LABELER so we won't come here again. if (isPair(type)) { if (gotKey(toss, toss, f0.labeler, type)) { return false; } else { refObject pars; setKey(f0.labeler, type, nil, nil); switch (toHook(car(type))) // Visit a trivially Skolemizable type. An ALTS, FORM, or GEN type can have an // ALTS type as a subtype. A REF or ROW type can have NULL as a subtype. { case altsHook: case arraysHook: case formHook: case genHook: case jokerHook: case referHook: case rowHook: case skoHook: case tuplesHook: { return true; } // Visit a type that is trivially not Skolemizable. case cellHook: case char0Hook: case char1Hook: case int0Hook: case int1Hook: case int2Hook: case listHook: case nullHook: case real0Hook: case real1Hook: case strTypeHook: case symHook: case voidHook: { return false; } // Visit an ARRAY type. It's Skolemizable if its base type is. case arrayHook: { type = caddr(type); break; } // Visit a PROC type. It's Skolemizable if (1) it has a Skolemizable parameter // type, (2) it has the missing name NO NAME as a parameter name, (3) it has a // Skolemizable yield type. case procHook: { type = cdr(type); pars = car(type); while (pars != nil) { pars = cdr(pars); if (car(pars) == noName) { return true; } else { pars = cdr(pars); }} pars = car(type); while (pars != nil) { if (isSkolemizable(layer, car(pars))) { return true; } else { pars = cddr(pars); }} type = cadr(type); break; } // Visit a TUPLE type. It's Skolemizable if it has a Skolemizable slot type or // if it has the missing name NO NAME as a slot name. case tupleHook: { pars = cdr(type); while (pars != nil) { pars = cdr(pars); if (car(pars) == noName) { return true; } else { pars = cdr(pars); }} pars = cdr(type); while (pars != nil) { if (isSkolemizable(layer, car(pars))) { return true; } else { pars = cddr(pars); }} return false; } // Visit a prefix type. It's Skolemizable if its base type is. case typeHook: case varHook: { type = cadr(type); break; } // Visit an illegal type. We should never get here. default: { fail("Got ?%s(...) in isSkolemizable!", hookTo(car(type))); }}}} // Visit an illegal object. We should never get here either. else { fail("Got bad type in isSkolemizable!"); }}} // Lost? This is SKOLEMIZE's body. These identities show what's going on. // // S(type T B) => T S(B) // S(U) => ?sko(U) // S(V) => V // // Here S(X) is the Skolem type for type X. T is a series of zero or more TYPE // prefixes. B is a type, U is a type with at least one subtype different from // itself, and V is a type with no subtypes different from itself. push(f0, 6); f0.labeler = pushLayer(nil, plainInfo); f0.layer = layer; f0.type = type; while (isName(f0.type)) { getKey(r(f0.layer), r(f0.type), f0.layer, f0.type); } if (isCar(f0.type, typeHook)) { f0.type = cadr(f0.type); if (isSkolemizable(f0.layer, f0.type)) { if (isCar(f0.type, typeHook)) { f0.first = f0.last = makePair(hooks[typeHook], nil); f0.type = cadr(f0.type); while (isCar(f0.type, typeHook)) { f0.next = makePair(hooks[typeHook], nil); cdr(f0.last) = makePair(f0.next, nil); f0.last = f0.next; f0.type = cadr(f0.type); } f0.next = makePrefix(skoHook, f0.type); cdr(f0.last) = makePair(f0.next, nil); } else { f0.first = makePrefix(skoHook, f0.type); }} else { f0.first = makePair(car(f0.type), cdr(f0.type)); }} else { fail("Type type expected in skolemize!"); } pop(); destroyLayer(f0.labeler); return f0.first; }
int main(int argc, char *argv[]) { NODE *exec_list = NIL; NODE *cl_tail = NIL; int argc2; char **argv2; bottom_stack = &exec_list; /*GC*/ (void) addseg(); term_init(); init(); math_init(); my_init(); signal(SIGINT, logo_stop); if (argc < 2) { if (1 || isatty(1)) // fix this. for interactive from menu bar. { char version[20]; lcleartext(NIL); strcpy(version, "5.6"); ndprintf(stdout, message_texts[WELCOME_TO], version); new_line(stdout); } } setvalnode__caseobj(LogoVersion, make_floatnode(5.6)); setflag__caseobj(LogoVersion, VAL_BURIED); argv2 = argv; argc2 = argc; if (!strcmp(*argv + strlen(*argv) - 4, "logo")) { argv++; while (--argc > 0 && strcmp(*argv, "-") && NOT_THROWING) { argv++; } } argv++; while (--argc > 0) { if (command_line == NIL) cl_tail = command_line = cons(make_static_strnode(*argv++), NIL); else { setcdr(cl_tail, cons(make_static_strnode(*argv++), NIL)); cl_tail = cdr(cl_tail); } } setvalnode__caseobj(CommandLine, command_line); silent_load(Startuplg, logolib); silent_load(Startup, NULL); /* load startup.lg */ if (!strcmp(*argv2 + strlen(*argv2) - 4, "logo")) { argv2++; while (--argc2 > 0 && strcmp(*argv2, "-") && NOT_THROWING) { silent_load(NIL, *argv2++); } } for (;;) { if (NOT_THROWING) { check_reserve_tank(); current_line = reader(stdin, "? "); if (feof(stdin) && !isatty(0)) lbye(NIL); if (NOT_THROWING) { exec_list = parser(current_line, TRUE); if (exec_list != NIL) eval_driver(exec_list); } } if (stopping_flag == THROWING) { if (isName(throw_node, Name_error)) { err_print(NULL); } else if (isName(throw_node, Name_system)) break; else if (!isName(throw_node, Name_toplevel)) { err_logo(NO_CATCH_TAG, throw_node); err_print(NULL); } stopping_flag = RUN; } if (stopping_flag == STOP || stopping_flag == OUTPUT) { /* ndprintf(stdout, "%t\n", message_texts[CANT_STOP]); */ stopping_flag = RUN; } } //prepare_to_exit(TRUE); my_finish(); exit(0); return 0; }
// This returns the parsed expression as a node, or NULL. If NULL is returned, error is made to point at an error message. All named indices less than or equal to global // are considered global; all other indices should be bound lambdas. u32 parseExpression( LNZprogram* p, const u8* string, u64 length, const char** error ){ *error = NULL; const u8* s = string; u64 l = length; // Eat up whitespace in front and back. while( l && isWhitespace( *s ) ){ --l; ++s; } while( l && isWhitespace( s[ l - 1 ] ) ) --l; if( !l ){ *error = "Syntax error: null expression."; return s - string; } // Handle lambdas if( *s == '\\' ){ ++s; --l; while( l && isWhitespace( *s ) ){ --l; ++s; } if( !l || !isName( *s ) ){ *error = "Syntax error: malformed lambda, expected an identifier."; return s - string; } // Eat identifiers, add them to the nametables, and build up an empty lambda at // top. u64 lambdaCount = 0; u32 cur, top; do{ u64 namelen = 0; while( namelen < l && isName( s[ namelen ] ) ) ++namelen; u32 newnode = mallocNode( p ); p->heap[ newnode ].type = LNZ_LAMBDA_TYPE; p->heap[ newnode ].references = 1; if( lambdaCount ) p->heap[ cur ].data = newnode; else top = newnode; ++lambdaCount; cur = newnode; addNamePointerPair( p, s, namelen, newnode ); // Eat trailing namespace while( namelen < l && isWhitespace( s[ namelen ] ) ) ++namelen; if( namelen == l || ( s[ namelen ] != '.' && !isName( s[ namelen ] ) ) ){ *error = "Syntax error: malformed lambda, expected '.' or an identifier."; return ( s - string ) + namelen; } s += namelen; l -= namelen; }while( *s != '.' ); // Parse the body. u32 pe = parseExpression( p, s + 1, l - 1, error ); if( *error != NULL ) return ( s - string ) + 1 + pe; p->heap[ cur ].data = pe; // Pop scope. while( lambdaCount ){ --lambdaCount; popNamePointerPair( p ); } return top; } // Handle applications,free variables, numbers and strings. u64 applicationCount = 0; u32 top; // Read one expression at a time; must be parenthetical or a name. do{ u32 arg; u64 namelen = 0; // Handle strings. if( s[ namelen ] == '\'' ){ ++namelen; u32 nullstring = mallocNode( p ); p->heap[ nullstring ].type = LNZ_DATA_TYPE; p->heap[ nullstring ].references = 0; // size. p->heap[ nullstring ].data = 0; arg = mallocNode( p ); p->heap[ arg ].type = LNZ_STRING_TYPE; p->heap[ arg ].references = 1; // size. p->heap[ arg ].data = ( (u64)nullstring ) << 32; p->heap[ arg ].data += ( (u64)nullstring ); u64 bsc = 0; while( namelen < l ){ if( s[ namelen ] == '\'' ){ while( bsc >= 2 ){ bsc -= 2; addStringChar( p, arg, '\\' ); } if( bsc ){ addStringChar( p, arg, '\'' ); bsc = 0; }else break; }else if( s[ namelen ] == '\\' ){ ++bsc; }else{ while( bsc >= 2 ){ bsc -= 2; addStringChar( p, arg, '\\' ); } bsc = 0; addStringChar( p, arg, s[ namelen ] ); } ++namelen; } if( namelen == l || s[ namelen ] != '\'' ){ *error = "Syntax error: malformed string."; return ( s - string ) + namelen; } ++namelen; // Handle parenthetical subexpressions. }else if( *s == '[' ){ namelen = 1; u64 f = 1; // scan for parentheses. u64 bsc = 0; u64 qm = 0; while( namelen < l ){ if( s[ namelen ] == '\\' ) ++bsc; else if( s[ namelen ] == '\'' ){ if( !( bsc % 2 ) && qm ) qm = 0; else if( !( bsc % 2 ) && !qm ) qm = 1; bsc = 0; }else{ if( !qm && s[ namelen ] == '[' ) ++f; if( !qm && s[ namelen ] == ']' ) --f; bsc = 0; } ++namelen; if( !f ) break; } if( f || namelen < 2 ){ *error = "Syntax error: unbalanced parentheses."; return s - string; } arg = parseExpression( p, s + 1, namelen - 2, error ); if( *error != NULL ) return ( s - string ) + 1 + arg; }else{ if( !l || !isName( *s ) ){ *error = "Syntax error: malformed expression."; return s - string; } // Handle identifiers and integers. while( namelen < l && isName( s[ namelen ] ) ) ++namelen; u64 isint = 1; u64 isminus = 0; u64 i = 0; if( s[ i ] == '-' ){ ++i; isminus = 1; if( namelen == 1 ) isint = 0; } for( ; i < namelen; ++i ) if( !isNumber( s[ i ] ) ) isint = 0; if( isint ){ arg = mallocNode( p ); u32 dn = mallocNode( p ); p->heap[ arg ].type = LNZ_INT_TYPE + isminus; p->heap[ arg ].references = 1; p->heap[ arg ].data = ( ( (u64)dn ) << 32 ) + ( (u64)dn ); p->heap[ dn ].type = LNZ_DATA_TYPE; p->heap[ dn ].references = 1; p->heap[ dn ].data = 0; i = 0; if( s[ i ] == '-' ) ++i; while( i < namelen && isNumber( s[ i ] ) ){ multiplyNumberByInt( p, arg, 10 ); addIntToNumber( p, arg, s[ i ] - '0' ); ++i; } }else{ u64 nind = getIndex( p->names, s, namelen ); if( !nind ){ *error = "Unknown identifier."; return s - string; } u32 pntr = getPointerFromName( p, s, namelen ); // if global or not a lambda, treat as an identifier, otherwise a free variable. if( nind <= p->global || p->heap[ pntr ].type != LNZ_LAMBDA_TYPE ) arg = *( ( u32* )( getName( p->pointers, nind, NULL ) ) ); else{ arg = mallocNode( p ); p->heap[ arg ].type = LNZ_FREE_TYPE; p->heap[ arg ].references = 1; p->heap[ arg ].data = *( ( u32* )( getName( p->pointers, nind, NULL ) ) ); } } } u32 newnode; if( applicationCount == 1 ) newnode = top; else{ newnode = mallocNode( p ); p->heap[ newnode ].data = 0; } p->heap[ newnode ].type = LNZ_APPLICATION_TYPE; p->heap[ newnode ].references = 1; p->heap[ newnode ].data += ( (u64)arg ) << 32; if( applicationCount > 1 ){ p->heap[ newnode ].data += top; } else if( !applicationCount ) p->heap[ newnode ].data >>= 32; top = newnode; ++applicationCount; // Eat up trailing whitespace. while( namelen < l && isWhitespace( s[ namelen ] ) ) ++namelen; s += namelen; l -= namelen; }while( l ); if( applicationCount == 1 ){ u32 ans = p->heap[ top ].data; freeNode( p, top ); return ans; }else{ return top; } }
u64 parseLine( LNZprogram* p, const u8* string, u64 length, const char **error ){ const u8* s = string; u64 l = length; // Eat up white space and parse an lvalue. while( l && isWhitespace( *s ) ){ ++s; --l; } u64 namelen = 0; while( namelen < l && isName( s[ namelen ] ) ) ++namelen; if( !namelen || namelen >= l ){ *error = "Syntax error: malformed equation"; return s - string; } const u8* name = s; s += namelen; l -= namelen; // Eat up white space and parse an =. while( l && isWhitespace( *s ) ){ ++s; --l; } if( !l || *s != '=' ){ *error = "Syntax error: malformed equation, expected an =."; return s - string; } ++s; --l; // scan for semicolon. u64 exprlen = 0; int qm = 0; u64 bsc = 0; while( exprlen < l ){ if( s[ exprlen ] == '\\' ) ++bsc; else if( s[ exprlen ] == '\'' ){ if( !( bsc % 2 ) && qm ) qm = 0; else if( !( bsc % 2 ) && !qm ) qm = 1; bsc = 0; }else{ bsc = 0; if( !qm && s[ exprlen ] == ';' ) break; } ++exprlen; } if( !exprlen || exprlen == l ){ *error = "Syntax error: malformed equation, expected an expression and a ;."; return s - string; } u32 expr = parseExpression( p, s, exprlen, error ); if( *error != NULL ) return ( s - string ) + expr; if( getIndex( p->names, name, namelen ) ){ *error = "Redefinition of an identifier."; return name - string; } addNamePointerPair( p, name, namelen, expr ); ++p->global; s += exprlen + 1; l -= exprlen + 1; while( l && isWhitespace( *s ) ){ ++s; --l; } return s - string; }