Scanner::Scanner(kstring name, Syntax &stx, Positions &pos, Errors &err) // ---------------------------------------------------------------------------- // Open the file and make sure it's readable // ---------------------------------------------------------------------------- : syntax(stx), input(*new utf8_ifstream(name)), tokenText(""), textValue(""), realValue(0.0), intValue(0), base(10), indents(), indent(0), indentChar(0), position(0), lineStart(0), positions(pos), errors(err), caseSensitive(Options::options ? Options::options->case_sensitive : true), checkingIndent(false), settingIndent(false), hadSpaceBefore(false), hadSpaceAfter(false), mustDeleteInput(true) { indents.push_back(0); // We start with an indent of 0 position = positions.OpenFile(name); if (input.fail()) err.Log(Error("File $1 cannot be read: $2", position). Arg(name).Arg(strerror(errno))); // Skip UTF-8 BOM if present if (input.get() != 0xEF) input.unget(); else if (input.get() != 0xBB) input.unget(), input.unget(); else if(input.get() != 0xBF) input.unget(), input.unget(), input.unget(); }
Scanner::Scanner(std::istream &input, Syntax &stx, Positions &pos, Errors &err, kstring fileName) // ---------------------------------------------------------------------------- // Open the file and make sure it's readable // ---------------------------------------------------------------------------- : syntax(stx), input(input), tokenText(""), textValue(""), realValue(0.0), intValue(0), base(10), indents(), indent(0), indentChar(0), position(0), lineStart(0), positions(pos), errors(err), caseSensitive(Options::options ? Options::options->case_sensitive : true), checkingIndent(false), settingIndent(false), hadSpaceBefore(false), hadSpaceAfter(false), mustDeleteInput(false) { indents.push_back(0); // We start with an indent of 0 position = positions.OpenFile(fileName); if (input.fail()) err.Log(Error("Input stream cannot be read: $1", position) .Arg(strerror(errno))); }
bool TypeInference::Evaluate(Tree *what) // ---------------------------------------------------------------------------- // Find candidates for the given expression and infer types from that // ---------------------------------------------------------------------------- { // We don't evaluate expressions while prototyping a pattern if (prototyping) return true; // Record if we are matching patterns bool matchingPattern = matching; matching = false; // Look directly inside blocks while (Block *block = what->AsBlock()) what = block->child; // Evaluating constants is always successful if (what->IsConstant() && !context->hasConstants) return AssignType(what, what); // Test if we are already trying to evaluate this particular form rcall_map::iterator found = rcalls.find(what); bool recursive = found != rcalls.end(); if (recursive) return true; // Identify all candidate rewrites in the current context RewriteCalls_p rc = new RewriteCalls(this); rcalls[what] = rc; uint count = 0; ulong key = context->Hash(what); Errors errors; errors.Log (Error("Unable to evaluate $1 because", what), true); context->Evaluate(what, *rc, key, Context::NORMAL_LOOKUP); // If we have no candidate, this is a failure count = rc->candidates.size(); if (count == 0) { if (matchingPattern && what->Kind() > KIND_LEAF_LAST) { Tree *wtype = Type(what); return Unify(wtype, tree_type, what, what); } Ooops("No form matches $1", what); return false; } errors.Clear(); errors.Log(Error("Unable to check types in $1 because", what), true); // The resulting type is the union of all candidates Tree *type = Base(rc->candidates[0].type); Tree *wtype = Type(what); for (uint i = 1; i < count; i++) { Tree *ctype = rc->candidates[i].type; ctype = Base(ctype); if (IsGeneric(ctype) && IsGeneric(wtype)) { // foo:#A rewritten as bar:#B and another type // Join types instead of performing a union if (!Join(ctype, type)) return false; if (!Join(wtype, type)) return false; continue; } type = UnionType(context, type, ctype); } // Perform type unification return Unify(type, wtype, what, what, DECLARATION); }