src/compiler/SemanticAnalysis.cpp
changeset 256 3c184218462d
parent 251 ca99a81745fe
child 258 241d082d6d89
     1.1 --- a/src/compiler/SemanticAnalysis.cpp	Tue Jan 01 20:08:34 2013 -0800
     1.2 +++ b/src/compiler/SemanticAnalysis.cpp	Sun Jan 06 13:52:21 2013 -0800
     1.3 @@ -93,11 +93,6 @@
     1.4          stmt->accept(this);
     1.5      }
     1.6  
     1.7 -    Local<Struct> globals(zone_, unit_->globalScope()->build(zone_));
     1.8 -    if (!globals)
     1.9 -        return;
    1.10 -    unit_->module()->setGlobals(globals);
    1.11 -
    1.12      Local<Code> code(zone_, __ finish());
    1.13      if (!code)
    1.14          return;
    1.15 @@ -448,7 +443,7 @@
    1.16              __ float_(0);
    1.17          } else if (type->isArray()) {
    1.18              Local<ArrayType> atype(zone_, ArrayType::cast(type));
    1.19 -            Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, atype));
    1.20 +            Local<ArrayMap> map(zone_, atype->newMap());
    1.21              if (!map)
    1.22                  return;
    1.23  
    1.24 @@ -570,6 +565,13 @@
    1.25      Symbol *sym = proxy->sym();
    1.26  
    1.27      switch (sym->kind()) {
    1.28 +      case Symbol::kImport:
    1.29 +      {
    1.30 +        ImportSymbol *import = sym->toImport();
    1.31 +        hir_ = new (pool_) HImport(proxy, sym->type(), import->index());
    1.32 +        break;
    1.33 +      }
    1.34 +
    1.35        case Symbol::kConstant:
    1.36        {
    1.37          ConstantSymbol *val = sym->toConstant();
    1.38 @@ -936,7 +938,7 @@
    1.39          // Transform the string literal into an array literal. We give it the
    1.40          // type of the left-hand side. The constness of the destination type
    1.41          // will determine whether HArray duplicates it or not.
    1.42 -        Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, actual));
    1.43 +        Local<ArrayMap> map(zone_, actual->newMap());
    1.44          if (!map)
    1.45              return NULL;
    1.46  
    1.47 @@ -1066,6 +1068,10 @@
    1.48  {
    1.49      Local<Type> from(zone_, hir->type());
    1.50  
    1.51 +    // If the source is *ever* an importable, we just fail.
    1.52 +    if (from->isImportable())
    1.53 +        return typeFailure(hir->node()->pos(), from, to);
    1.54 +
    1.55      if (from->isInt32() && to->isFloat())
    1.56          return new (pool_) HConvert(hir->node(), to, OP_CVT_I2F, hir);
    1.57      if (from->isInt32() && to->isBool())
    1.58 @@ -1218,6 +1224,70 @@
    1.59      }
    1.60  }
    1.61  
    1.62 +void
    1.63 +SemanticAnalysis::import(HIR *hir, FieldExpression *node)
    1.64 +{
    1.65 +    // Note that we don't care if the hir type is "importable", since we
    1.66 +    // can only do anything if the important has a constant binding.
    1.67 +    unsigned index = hir->toImport()->index();
    1.68 +    Local<Importable> importable(zone_, unit_->module()->getImportAt(index));
    1.69 +
    1.70 +    if (importable->isPackage()) {
    1.71 +        // Look at what's already loaded and see if anything exists. We
    1.72 +        // can't create stuff on-demand here since it's too late to add
    1.73 +        // new translation units to the CompileContext.
    1.74 +        Local<Package> package(zone_, Package::cast(importable));
    1.75 +        Local<Importable> found(zone_, package->import(node->field()));
    1.76 +        if (!found) {
    1.77 +            cc_.reportError(node->pos(), Message_PackageDoesNotHaveMember, node->field()->chars());
    1.78 +            return;
    1.79 +        }
    1.80 +
    1.81 +        // If we did find something, make sure it is in our import list.
    1.82 +        // If we didn't explicitly import it, we have no right to use it.
    1.83 +        for (index = 0; index < unit_->module()->imports(); index++) {
    1.84 +            if (unit_->module()->getImportAt(index) == importable)
    1.85 +                break;
    1.86 +        }
    1.87 +
    1.88 +        if (index == unit_->module()->imports()) {
    1.89 +            cc_.reportError(node->pos(), Message_ImportWasNeverImported, node->field()->chars());
    1.90 +            return;
    1.91 +        }
    1.92 +
    1.93 +        // Just create a new HImport.
    1.94 +        hir_ = new (pool_) HImport(node, hir->type(), index);
    1.95 +    } else {
    1.96 +        // Modules can never have sub-modules or sub-packages.
    1.97 +        unsigned index;
    1.98 +        Local<Module> module(zone_, Module::cast(importable));
    1.99 +        Local<StructMap> map(zone_, module->globals()->map());
   1.100 +        Local<Descriptor> desc(zone_, map->type()->lookupField(node->field(), &index));
   1.101 +        if (!desc) {
   1.102 +            cc_.reportError(node->pos(), Message_FieldNotFound, node->field()->chars());
   1.103 +            return;
   1.104 +        }
   1.105 +        hir_ = new (pool_) HField(node, hir, desc->type(), index);
   1.106 +    }
   1.107 +}
   1.108 +
   1.109 +void
   1.110 +SemanticAnalysis::visitFieldExpression(FieldExpression *node)
   1.111 +{
   1.112 +    HIR *hir = eval(node->left());
   1.113 +    if (!hir)
   1.114 +        return;
   1.115 +
   1.116 +    if (hir->isImport()) {
   1.117 +        import(hir, node);
   1.118 +        return;
   1.119 +    }
   1.120 +
   1.121 +    char name[255];
   1.122 +    cc_.reportError(node->pos(), Message_InvalidFieldExpression,
   1.123 +                    GetTypeName(hir->type(), name, sizeof(name)));
   1.124 +}
   1.125 +
   1.126  static inline TokenKind
   1.127  ToCompare(Expression *expr)
   1.128  {