Ejemplo n.º 1
0
Archivo: scanner.cpp Proyecto: c3d/elfe
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();
}
Ejemplo n.º 2
0
Archivo: scanner.cpp Proyecto: c3d/elfe
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)));
}
Ejemplo n.º 3
0
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);
}