Initial implementation of module imports.
Initial implementation of module imports.
1.1 --- a/src/Array.cpp Tue Jan 01 20:08:34 2013 -0800
1.2 +++ b/src/Array.cpp Sun Jan 06 13:52:21 2013 -0800
1.3 @@ -50,27 +50,6 @@
1.4 return map;
1.5 }
1.6
1.7 -ArrayMap *
1.8 -ArrayMap::Attach(Zone *zone, Handle<ArrayType> type)
1.9 -{
1.10 - if (type->newMap())
1.11 - return ArrayMap::cast(type->newMap());
1.12 -
1.13 - Local<ArrayMap> map(zone, ArrayMap::New(zone, type));
1.14 - if (!map)
1.15 - return NULL;
1.16 -
1.17 - // Ensure the inner type has an ArrayMap if needed.
1.18 - if (type->contained()->isArray()) {
1.19 - Local<ArrayType> contained(zone, ArrayType::cast(type->contained()));
1.20 - if (!ArrayMap::Attach(zone, contained))
1.21 - return NULL;
1.22 - }
1.23 -
1.24 - type->setNewMap(map);
1.25 - return map;
1.26 -}
1.27 -
1.28 Array *
1.29 Array::NewRaw(Zone *zone, Handle<ArrayMap> map, unsigned nelements, Heap::Tenure tenure)
1.30 {
2.1 --- a/src/Array.h Tue Jan 01 20:08:34 2013 -0800
2.2 +++ b/src/Array.h Sun Jan 06 13:52:21 2013 -0800
2.3 @@ -166,12 +166,7 @@
2.4 Barriered<ArrayType> type_;
2.5
2.6 public:
2.7 - // The way array maps work is kind of clownshoes. In the future, these
2.8 - // should be created immediately (or lazily) on the Type directly, and not
2.9 - // manually created via ::Attach. :TODO: do this when we begin caching
2.10 - // array types.
2.11 static ArrayMap *New(Zone *zone, Handle<ArrayType> type);
2.12 - static ArrayMap *Attach(Zone *zone, Handle<ArrayType> type);
2.13
2.14 // DependentArray maps are never attached, and are just free-floating,
2.15 // rooted ultimately by the bytecode. A :TODO: that we might need to
3.1 --- a/src/Handles.h Tue Jan 01 20:08:34 2013 -0800
3.2 +++ b/src/Handles.h Sun Jan 06 13:52:21 2013 -0800
3.3 @@ -170,7 +170,7 @@
3.4 // A ScopedRoot is a special kind of handle for storing references on the
3.5 // heap in bulk.
3.6 template <typename T>
3.7 -class ScopedRoot
3.8 +class ScopedRoot : public PoolObject
3.9 {
3.10 T **thingp_;
3.11
4.1 --- a/src/Heap-inl.h Tue Jan 01 20:08:34 2013 -0800
4.2 +++ b/src/Heap-inl.h Sun Jan 06 13:52:21 2013 -0800
4.3 @@ -75,7 +75,7 @@
4.4 size_t actualBytes = Align(bytes, kObjectAlignment);
4.5
4.6 // All objects must be at least two words.
4.7 - assert(actualBytes >= sizeof(Object *) * 2);
4.8 + assert(actualBytes >= kMinObjectSize);
4.9
4.10 Address address = newObject(actualBytes, age);
4.11 if (!address) {
5.1 --- a/src/Interpreter.cpp Tue Jan 01 20:08:34 2013 -0800
5.2 +++ b/src/Interpreter.cpp Sun Jan 06 13:52:21 2013 -0800
5.3 @@ -898,7 +898,11 @@
5.4
5.5 case OP_GETFIELD:
5.6 {
5.7 - Struct *obj = Struct::cast(top.sp[-1].obj);
5.8 + Struct *obj;
5.9 + if (top.sp[-1].obj->is(MapKind_Module))
5.10 + obj = Module::cast(top.sp[-1].obj)->globals();
5.11 + else
5.12 + obj = Struct::cast(top.sp[-1].obj);
5.13 GetField(obj, READ_UINT32(top.pc), &top.sp[-1]);
5.14 break;
5.15 }
5.16 @@ -1007,6 +1011,15 @@
5.17 break;
5.18 }
5.19
5.20 +case OP_IMPORT:
5.21 +{
5.22 + unsigned index = READ_UINT32(top.pc);
5.23 +
5.24 + top.sp++;
5.25 + top.sp[-1].obj = top.fp->code()->module()->getImportAt(index);
5.26 + break;
5.27 +}
5.28 +
5.29 default:
5.30 assert(false);
5.31 return false;
6.1 --- a/src/Messages.tbl Tue Jan 01 20:08:34 2013 -0800
6.2 +++ b/src/Messages.tbl Sun Jan 06 13:52:21 2013 -0800
6.3 @@ -85,4 +85,9 @@
6.4 MSG(InvalidUncheckedCastFrom, TypeError, "cannot perform an unchecked cast on type '%s'")
6.5 MSG(InvalidUncheckedCastTo, TypeError, "cannot perform an unchecked cast to type '%s'")
6.6 MSG(InvalidUnaryType, TypeError, "operator %s not defined for type '%s'")
6.7 -MSG(CannotImportPath, SyntaxError, "could not find module or import '%s'")
6.8 \ No newline at end of file
6.9 +MSG(CannotImportPath, SyntaxError, "could not find module or import '%s'")
6.10 +MSG(DuplicateImport, SyntaxError, "duplicate import name '%s'")
6.11 +MSG(InvalidFieldExpression, TypeError, "type '%s' does not have any fields")
6.12 +MSG(PackageDoesNotHaveMember, TypeError, "package does not have member '%s' (check imports)")
6.13 +MSG(ImportWasNeverImported, TypeError, "'%s' was never imported")
6.14 +MSG(FieldNotFound, TypeError, "field '%s' not found")
6.15 \ No newline at end of file
7.1 --- a/src/Modules.h Tue Jan 01 20:08:34 2013 -0800
7.2 +++ b/src/Modules.h Sun Jan 06 13:52:21 2013 -0800
7.3 @@ -21,6 +21,7 @@
7.4 #include "Heap.h"
7.5 #include "Code.h"
7.6 #include "Functions.h"
7.7 +#include "FixedArray.h"
7.8 #include "Packages.h"
7.9
7.10 namespace ke {
7.11 @@ -36,6 +37,7 @@
7.12 Barriered<Struct> globals_;
7.13 void *nativeIdentity_;
7.14 TranslationUnit *unit_;
7.15 + Barriered<FixedArray> imports_;
7.16
7.17 public:
7.18 static Module *New(Zone *zone, Handle<Package> package, Handle<String> path, Handle<String> name);
7.19 @@ -63,6 +65,18 @@
7.20 unit_ = unit;
7.21 }
7.22
7.23 + unsigned imports() {
7.24 + return imports_ ? imports_->length() / 2 : 0;
7.25 + }
7.26 + Importable *getImportAt(unsigned index) {
7.27 + return Importable::cast(imports_->at(index * 2));
7.28 + }
7.29 + FixedArray *importPathAt(unsigned index) {
7.30 + return FixedArray::cast(imports_->at(index * 2 + 1));
7.31 + }
7.32 + void setImports(Handle<FixedArray> imports) {
7.33 + imports_ = imports;
7.34 + }
7.35 void setCode(Handle<Code> code) {
7.36 code_ = code;
7.37 }
7.38 @@ -77,6 +91,9 @@
7.39 static inline size_t offsetOfGlobals() {
7.40 return OFFSETOF(Module, globals_);
7.41 }
7.42 + static inline size_t offsetOfImports() {
7.43 + return OFFSETOF(Module, imports_);
7.44 + }
7.45 // End GC Descriptor.
7.46
7.47 static inline Module *cast(Object *obj) {
8.1 --- a/src/ObjectVisitor.h Tue Jan 01 20:08:34 2013 -0800
8.2 +++ b/src/ObjectVisitor.h Sun Jan 06 13:52:21 2013 -0800
8.3 @@ -125,6 +125,7 @@
8.4 visitImportable(obj);
8.5 visitField(obj, Module::offsetOfGlobals());
8.6 visitField(obj, Module::offsetOfCode());
8.7 + visitField(obj, Module::offsetOfImports());
8.8 return sizeof(Module);
8.9 }
8.10
8.11 @@ -213,7 +214,7 @@
8.12 unsigned noffsets = map->traceOffsetCount();
8.13 for (unsigned i = 0; i < noffsets; i++)
8.14 visitField(obj, Struct::offsetOfSlotOffset(offsets[i]));
8.15 - return obj->objSize();
8.16 + return Struct::SizeFor(map);
8.17 }
8.18
8.19 size_t iterateList(Object *obj) {
8.20 @@ -388,7 +389,7 @@
8.21 return sizeof(List<Object>);
8.22
8.23 case MapKind_Struct:
8.24 - return Struct::cast(obj)->objSize();
8.25 + return Struct::SizeFor(StructMap::cast(map));
8.26
8.27 case MapKind_EnvironmentSlotDescriptorArray:
8.28 return EnvironmentSlotDescriptorArray::cast(obj)->objSize();
9.1 --- a/src/Opcodes.cpp Tue Jan 01 20:08:34 2013 -0800
9.2 +++ b/src/Opcodes.cpp Sun Jan 06 13:52:21 2013 -0800
9.3 @@ -25,6 +25,7 @@
9.4 #include "Strings.h"
9.5 #include "CompactBuffer.h"
9.6 #include "Structures.h"
9.7 +#include "Modules.h"
9.8 #include "Heap-inl.h"
9.9
9.10 using namespace ke;
9.11 @@ -304,6 +305,19 @@
9.12 break;
9.13 }
9.14
9.15 + case OP_IMPORT:
9.16 + {
9.17 + unsigned index = READ_UINT32(pc);
9.18 + FixedArray *path = code->module()->importPathAt(index);
9.19 + fprintf(fp, " ; ");
9.20 + for (unsigned i = 0; i < path->length(); i++) {
9.21 + fprintf(fp, "%s", String::cast(path->at(i))->chars());
9.22 + if (i != path->length() - 1)
9.23 + fprintf(fp, ".");
9.24 + }
9.25 + break;
9.26 + }
9.27 +
9.28 default:
9.29 // Unknown opcode!
9.30 assert(false);
10.1 --- a/src/Opcodes.tbl Tue Jan 01 20:08:34 2013 -0800
10.2 +++ b/src/Opcodes.tbl Sun Jan 06 13:52:21 2013 -0800
10.3 @@ -265,4 +265,7 @@
10.4 // index = POP()
10.5 // base = POP()
10.6 // PUSH(array)
10.7 -OPDEF(OP_DEPARRAY, "deparray", 5, 2, 1)
10.8 \ No newline at end of file
10.9 +OPDEF(OP_DEPARRAY, "deparray", 5, 2, 1)
10.10 +
10.11 +// Grabs an import object from the import table.
10.12 +OPDEF(OP_IMPORT, "import", 5, 0, 1)
10.13 \ No newline at end of file
11.1 --- a/src/Packages.cpp Tue Jan 01 20:08:34 2013 -0800
11.2 +++ b/src/Packages.cpp Sun Jan 06 13:52:21 2013 -0800
11.3 @@ -69,6 +69,12 @@
11.4 return false;
11.5 }
11.6
11.7 +#ifndef NDEBUG
11.8 + // Assert no duplicate names.
11.9 + for (unsigned i = 0; i < pkg->contents_->length(); i++)
11.10 + assert(pkg->contents_->at(i)->name() != obj->name());
11.11 +#endif
11.12 +
11.13 if (!pkg->contents_->append(zone, obj))
11.14 return false;
11.15
12.1 --- a/src/Spaces.h Tue Jan 01 20:08:34 2013 -0800
12.2 +++ b/src/Spaces.h Sun Jan 06 13:52:21 2013 -0800
12.3 @@ -30,6 +30,7 @@
12.4 class Map;
12.5
12.6 static const size_t kObjectAlignment = sizeof(Object *);
12.7 +static const size_t kMinObjectSize = sizeof(Object *) * 2;
12.8
12.9 // Every object gets two successive mark bits. These bits represent various
12.10 // states during garbage collection:
13.1 --- a/src/Structures.cpp Tue Jan 01 20:08:34 2013 -0800
13.2 +++ b/src/Structures.cpp Sun Jan 06 13:52:21 2013 -0800
13.3 @@ -56,7 +56,7 @@
13.4 }
13.5
13.6 Descriptor *
13.7 -Descriptor::New(Zone *zone, Handle<String> name, Handle<Type> type)
13.8 +Descriptor::New(Zone *zone, Handle<String> name, Handle<Type> type, Visibility visibility)
13.9 {
13.10 Local<Descriptor> desc(zone,
13.11 Descriptor::cast(zone->allocate(MapKind_Descriptor, sizeof(Descriptor), Heap::Tenure_Old)));
13.12 @@ -66,6 +66,7 @@
13.13 desc->name_ = name;
13.14 desc->type_ = type;
13.15 desc->offset_ = unsigned(-1);
13.16 + desc->visibility_ = visibility;
13.17 return desc;
13.18 }
13.19
13.20 @@ -111,12 +112,13 @@
13.21 Struct *
13.22 Struct::New(Zone *zone, Handle<StructMap> map, Heap::Tenure tenure)
13.23 {
13.24 - size_t bytesNeeded = sizeof(Struct) + map->structureSize();
13.25 + size_t bytesNeeded = SizeFor(map);
13.26 +
13.27 Local<Struct> obj(zone, Struct::cast(zone->allocate(map, bytesNeeded, tenure)));
13.28 if (!obj)
13.29 return NULL;
13.30
13.31 - memset((Struct *)obj + 1, 0, map->structureSize());
13.32 + memset((Struct *)obj + 1, 0, (bytesNeeded - sizeof(Struct)));
13.33
13.34 // Initialize any sub-structures. Right now, this is performed as part of
13.35 // struct allocation, rather than inlined in bytecode, for simplicity.
14.1 --- a/src/Structures.h Tue Jan 01 20:08:34 2013 -0800
14.2 +++ b/src/Structures.h Sun Jan 06 13:52:21 2013 -0800
14.3 @@ -60,6 +60,14 @@
14.4 // Represents a property descriptor for a structure field.
14.5 class Descriptor : public Object
14.6 {
14.7 + public:
14.8 + enum Visibility {
14.9 + Private,
14.10 + Protected,
14.11 + Public
14.12 + };
14.13 +
14.14 + private:
14.15 // The name of the field.
14.16 Barriered<String> name_;
14.17
14.18 @@ -69,8 +77,10 @@
14.19 // The offset into an object at which this field can be accessed.
14.20 unsigned offset_;
14.21
14.22 + Visibility visibility_;
14.23 +
14.24 public:
14.25 - static Descriptor *New(Zone *zone, Handle<String> name, Handle<Type> type);
14.26 + static Descriptor *New(Zone *zone, Handle<String> name, Handle<Type> type, Visibility visibility);
14.27
14.28 String *name() {
14.29 return name_;
14.30 @@ -160,9 +170,6 @@
14.31
14.32 static bool Copy(Zone *zone, Handle<Struct> dest, Handle<Struct> src);
14.33
14.34 - size_t objSize() {
14.35 - return sizeof(Struct) + map()->structureSize();
14.36 - }
14.37 StructMap *map() {
14.38 return StructMap::cast(Object::map());
14.39 }
14.40 @@ -171,6 +178,10 @@
14.41 return reinterpret_cast<Address>(this) + offsetOfSlotOffset(desc->offset());
14.42 }
14.43
14.44 + static inline size_t SizeFor(StructMap *map) {
14.45 + return Max(sizeof(Struct) + map->structureSize(), kMinObjectSize);
14.46 + }
14.47 +
14.48 template <typename T> T get(Descriptor *desc) {
14.49 return *reinterpret_cast<T *>(ref(desc));
14.50 }
15.1 --- a/src/TypeManager.cpp Tue Jan 01 20:08:34 2013 -0800
15.2 +++ b/src/TypeManager.cpp Sun Jan 06 13:52:21 2013 -0800
15.3 @@ -48,6 +48,10 @@
15.4 if (!stringType_)
15.5 return false;
15.6
15.7 + importableType_ = Type::NewImportable(zone_);
15.8 + if (!importableType_)
15.9 + return false;
15.10 +
15.11 if ((primitiveTypes_[PrimitiveType_Int32] = Type::NewPrimitive(zone_, PrimitiveType_Int32)) == NULL)
15.12 return false;
15.13 if ((primitiveTypes_[PrimitiveType_Float] = Type::NewPrimitive(zone_, PrimitiveType_Float)) == NULL)
15.14 @@ -136,6 +140,7 @@
15.15 visitor->visit(voidType_.address());
15.16 visitor->visit(uncheckedType_.address());
15.17 visitor->visit(stringType_.address());
15.18 + visitor->visit(importableType_.address());
15.19 for (unsigned i = 0; i < PrimitiveTypes_Total; i++) {
15.20 visitor->visit(primitiveTypes_[i].address());
15.21 visitor->visit(referenceTypes_[i].address());
16.1 --- a/src/TypeManager.h Tue Jan 01 20:08:34 2013 -0800
16.2 +++ b/src/TypeManager.h Sun Jan 06 13:52:21 2013 -0800
16.3 @@ -79,6 +79,9 @@
16.4 Type *getUnchecked() {
16.5 return uncheckedType_;
16.6 }
16.7 + Type *getImportable() {
16.8 + return importableType_;
16.9 + }
16.10 ReferenceType *getReference(Handle<Type> type, bool isConst);
16.11 ArrayType *newArray(Handle<Type> contained, int elements);
16.12 ArrayType *newExternalArray(Handle<Type> contained);
16.13 @@ -96,6 +99,7 @@
16.14 Unbarriered<Type> voidType_;
16.15 Unbarriered<Type> stringType_;
16.16 Unbarriered<Type> uncheckedType_;
16.17 + Unbarriered<Type> importableType_;
16.18 Unbarriered<Type> primitiveTypes_[PrimitiveTypes_Total];
16.19 Unbarriered<ReferenceType> referenceTypes_[PrimitiveTypes_Total];
16.20
17.1 --- a/src/Types.cpp Tue Jan 01 20:08:34 2013 -0800
17.2 +++ b/src/Types.cpp Sun Jan 06 13:52:21 2013 -0800
17.3 @@ -20,6 +20,7 @@
17.4 #include "Types.h"
17.5 #include "Zone.h"
17.6 #include "Strings.h"
17.7 +#include "Array.h"
17.8 #include "Structures.h"
17.9 #include "Heap-inl.h"
17.10
17.11 @@ -44,6 +45,17 @@
17.12 }
17.13
17.14 Type *
17.15 +Type::NewImportable(Zone *zone)
17.16 +{
17.17 + Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
17.18 + if (!type)
17.19 + return NULL;
17.20 +
17.21 + type->init(IMPORTABLE);
17.22 + return type;
17.23 +}
17.24 +
17.25 +Type *
17.26 Type::NewString(Zone *zone)
17.27 {
17.28 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
17.29 @@ -110,6 +122,11 @@
17.30 type->levels_ = 1;
17.31 else
17.32 type->levels_ = ArrayType::cast(contained)->levels() + 1;
17.33 +
17.34 + type->newMap_ = ArrayMap::New(zone, type);
17.35 + if (!type->newMap_)
17.36 + return NULL;
17.37 +
17.38 return type;
17.39 }
17.40
17.41 @@ -270,6 +287,8 @@
17.42 return Format(buffer, maxlen, "void");
17.43 if (type->isUnchecked())
17.44 return Format(buffer, maxlen, "unchecked");
17.45 + if (type->isImportable())
17.46 + return Format(buffer, maxlen, "import");
17.47 if (type->isEnum())
17.48 return Format(buffer, maxlen, "%s", EnumType::cast(type)->name()->chars());
17.49 if (type->isStruct())
18.1 --- a/src/Types.h Tue Jan 01 20:08:34 2013 -0800
18.2 +++ b/src/Types.h Sun Jan 06 13:52:21 2013 -0800
18.3 @@ -111,7 +111,11 @@
18.4
18.5 // Structs are composite records that may contain primitives, arrays,
18.6 // functions, enums, and other structs.
18.7 - STRUCT
18.8 + STRUCT,
18.9 +
18.10 + // Importable types are mainly used during the compilation process
18.11 + // to distinguish between normal names and static imports.
18.12 + IMPORTABLE
18.13 };
18.14
18.15 void init(Kind kind, Type *root = NULL);
18.16 @@ -127,6 +131,7 @@
18.17 static Type *NewPrimitive(Zone *zone, PrimitiveType type);
18.18 static Type *NewString(Zone *zone);
18.19 static Type *NewQualified(Zone *zone, TypeQualifiers qual, Handle<Type> type);
18.20 + static Type *NewImportable(Zone *zone);
18.21
18.22 static Type *cast(Object *obj) {
18.23 assert(!obj ||
18.24 @@ -160,6 +165,9 @@
18.25 bool isStruct() {
18.26 return kind() == STRUCT;
18.27 }
18.28 + bool isImportable() {
18.29 + return kind() == IMPORTABLE;
18.30 + }
18.31 PrimitiveType primitive() {
18.32 assert(isPrimitive());
18.33 return root_->primitive_;
19.1 --- a/src/Utility.h Tue Jan 01 20:08:34 2013 -0800
19.2 +++ b/src/Utility.h Sun Jan 06 13:52:21 2013 -0800
19.3 @@ -282,6 +282,12 @@
19.4 return t1 < t2 ? t1 : t2;
19.5 }
19.6
19.7 +template <typename T> static inline T
19.8 +Max(const T &t1, const T &t2)
19.9 +{
19.10 + return t1 > t2 ? t1 : t2;
19.11 +}
19.12 +
19.13 #define OFFSETOF(Class, Member) reinterpret_cast<size_t>(&((Class *)NULL)->Member)
19.14
19.15 }
20.1 --- a/src/compiler/AST.h Tue Jan 01 20:08:34 2013 -0800
20.2 +++ b/src/compiler/AST.h Sun Jan 06 13:52:21 2013 -0800
20.3 @@ -28,6 +28,7 @@
20.4 namespace ke {
20.5
20.6 class Scope;
20.7 +class Importable;
20.8 struct PathComponent;
20.9
20.10 #define ASTKINDS(_) \
20.11 @@ -128,21 +129,11 @@
20.12
20.13 class Expression : public AstNode
20.14 {
20.15 - ScopedRoot<Type> type_;
20.16 -
20.17 public:
20.18 Expression(const SourcePosition &pos)
20.19 - : AstNode(pos),
20.20 - type_(NULL)
20.21 + : AstNode(pos)
20.22 {
20.23 }
20.24 -
20.25 - void setType(Type *type) {
20.26 - type_ = type;
20.27 - }
20.28 - Type *type() const {
20.29 - return type_;
20.30 - }
20.31 };
20.32
20.33 typedef PoolList<Statement *> StatementList;
20.34 @@ -497,14 +488,12 @@
20.35 {
20.36 Expression *left_;
20.37 ScopedRoot<String> field_;
20.38 - unsigned fieldIndex_;
20.39
20.40 public:
20.41 FieldExpression(const SourcePosition &pos, Expression *left, Handle<String> field)
20.42 : Expression(pos),
20.43 left_(left),
20.44 - field_(field),
20.45 - fieldIndex_(unsigned(-1))
20.46 + field_(field)
20.47 {
20.48 }
20.49
20.50 @@ -513,17 +502,9 @@
20.51 Expression *left() const {
20.52 return left_;
20.53 }
20.54 - String *field() const {
20.55 + Handle<String> field() const {
20.56 return field_;
20.57 }
20.58 - void setFieldIndex(unsigned index) {
20.59 - assert(fieldIndex_ == unsigned(-1));
20.60 - fieldIndex_ = index;
20.61 - }
20.62 - unsigned fieldIndex() const {
20.63 - assert(fieldIndex_ != unsigned(-1));
20.64 - return fieldIndex_;
20.65 - }
20.66 };
20.67
20.68 class CallExpression : public Expression
20.69 @@ -1105,11 +1086,9 @@
20.70 class ImportStatement : public Statement
20.71 {
20.72 public:
20.73 - ImportStatement(const SourcePosition &pos, PathComponent *path, TokenKind suffix)
20.74 + ImportStatement(const SourcePosition &pos, PathComponent *path)
20.75 : Statement(pos),
20.76 - path_(path),
20.77 - suffix_(suffix),
20.78 - source_(NULL)
20.79 + path_(path)
20.80 {
20.81 }
20.82
20.83 @@ -1118,20 +1097,23 @@
20.84 PathComponent *path() const {
20.85 return path_;
20.86 }
20.87 - void setImportSource(TranslationUnit *unit) {
20.88 - source_ = unit;
20.89 + void setSource(Importable *source) {
20.90 + source_ = source;
20.91 }
20.92 - TranslationUnit *source() const {
20.93 + Handle<Importable> source() {
20.94 return source_;
20.95 }
20.96 - TokenKind suffix() const {
20.97 - return suffix_;
20.98 + unsigned importIndex() {
20.99 + return importIndex_;
20.100 + }
20.101 + void setImportIndex(unsigned index) {
20.102 + importIndex_ = index;
20.103 }
20.104
20.105 private:
20.106 PathComponent *path_;
20.107 - TokenKind suffix_;
20.108 - TranslationUnit *source_;
20.109 + ScopedRoot<Importable> source_;
20.110 + unsigned importIndex_;
20.111 };
20.112
20.113 typedef StructureStatement::FieldList FieldList;
21.1 --- a/src/compiler/BytecodeEmitter.h Tue Jan 01 20:08:34 2013 -0800
21.2 +++ b/src/compiler/BytecodeEmitter.h Sun Jan 06 13:52:21 2013 -0800
21.3 @@ -681,6 +681,13 @@
21.4 jump(labels[i]);
21.5 }
21.6
21.7 + void import(unsigned index) {
21.8 + ensure(OP_IMPORT_LENGTH);
21.9 + writeOp(OP_IMPORT);
21.10 + writeUint32(index);
21.11 + markOop(1);
21.12 + }
21.13 +
21.14 bool allocate(VariableSymbol *sym);
21.15
21.16 Code *finish();
22.1 --- a/src/compiler/CompileContext.cpp Tue Jan 01 20:08:34 2013 -0800
22.2 +++ b/src/compiler/CompileContext.cpp Sun Jan 06 13:52:21 2013 -0800
22.3 @@ -21,6 +21,8 @@
22.4 #include "../Interpreter.h"
22.5 #include "../Packages.h"
22.6 #include "../FileSystem.h"
22.7 +#include "../FixedArray.h"
22.8 +#include "../Vector.h"
22.9 #include "Scanner.h"
22.10 #include "CompileContext.h"
22.11 #include "Parser.h"
22.12 @@ -60,7 +62,7 @@
22.13 if (!strname)
22.14 return false;
22.15
22.16 - PathComponent p(new ScopedRoot<String>(strname), NULL);
22.17 + PathComponent p(new (zone_->pool()) ScopedRoot<String>(strname), NULL);
22.18
22.19 Local<Importable> importable(zone_);
22.20 if (!zone_->packages()->findOrAdd(package, &p, importable.address()))
22.21 @@ -145,10 +147,17 @@
22.22 {
22.23 PoolList<ImportStatement *> *imports = unit->tree()->imports();
22.24
22.25 + if (!imports->length())
22.26 + return true;
22.27 +
22.28 + // We're allowed to use Handle<> here instead of ScopedRoot<> because
22.29 + // we get the handle from ImportStatement which has a ScopedRoot<>.
22.30 + Vector<Handle<Importable> > vec;
22.31 +
22.32 for (size_t i = 0; i < imports->length(); i++) {
22.33 ImportStatement *import = imports->at(i);
22.34
22.35 - // Step 1. Crawl the path until we find a valid file to load.
22.36 + // Crawl the path until we find a valid file to load.
22.37 Local<Importable> obj(zone_);
22.38 Local<Package> package(zone_, unit->module()->parent());
22.39 if (!zone_->packages()->findOrAdd(package, import->path(), obj.address()))
22.40 @@ -170,8 +179,52 @@
22.41 if (!add(module))
22.42 return false;
22.43 }
22.44 +
22.45 + import->setSource(obj);
22.46 +
22.47 + // See if there are any duplicates. This is O(n^2), but we expect
22.48 + // |n| to be small.
22.49 + unsigned index = 0;
22.50 + for (; index < vec.length(); index++) {
22.51 + if (vec[index] == obj)
22.52 + break;
22.53 + }
22.54 + if (index == vec.length() && !vec.append(import->source()))
22.55 + return false;
22.56 +
22.57 + import->setImportIndex(index);
22.58 }
22.59
22.60 + if (!IsUint32MultiplySafe(vec.length(), 2)) {
22.61 + zone_->reportAllocationOverflow();
22.62 + return false;
22.63 + }
22.64 +
22.65 + // Create an array of the import and paths.
22.66 + Local<FixedArray> importables(zone_, FixedArray::New(zone_, vec.length() * 2, Heap::Tenure_Default));
22.67 + if (!importables)
22.68 + return false;
22.69 +
22.70 + for (unsigned i = 0; i < vec.length(); i++) {
22.71 + importables->set(zone_, i * 2, vec[i]);
22.72 +
22.73 + unsigned count = 0;
22.74 + PathComponent *path = imports->at(i)->path();
22.75 + for (PathComponent *iter = path; iter; iter = iter->next)
22.76 + count++;
22.77 +
22.78 + Local<FixedArray> list(zone_, FixedArray::New(zone_, count, Heap::Tenure_Default));
22.79 + if (!list)
22.80 + return false;
22.81 +
22.82 + count = 0;
22.83 + for (PathComponent *iter = path; iter; iter = iter->next, count++)
22.84 + list->set(zone_, count, iter->name);
22.85 +
22.86 + importables->set(zone_, i * 2 + 1, list);
22.87 + }
22.88 +
22.89 + unit->module()->setImports(importables);
22.90 return true;
22.91 }
22.92
23.1 --- a/src/compiler/HIR.cpp Tue Jan 01 20:08:34 2013 -0800
23.2 +++ b/src/compiler/HIR.cpp Sun Jan 06 13:52:21 2013 -0800
23.3 @@ -50,9 +50,11 @@
23.4 void visitGlobal(HGlobal *global);
23.5 void visitConvert(HConvert *convert);
23.6 void visitIndex(HIndex *index);
23.7 + void visitField(HField *field);
23.8 void visitPostIncDec(HPostIncDec *hir);
23.9 void visitToRef(HToRef *hir);
23.10 void visitNewDependentArray(HNewDependentArray *hir);
23.11 + void visitImport(HImport *import);
23.12
23.13 private:
23.14 Zone *zone_;
23.15 @@ -286,6 +288,45 @@
23.16 }
23.17
23.18 void
23.19 +HField::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
23.20 +{
23.21 + __ note_position(node()->pos());
23.22 + base_->accept(visitor);
23.23 +}
23.24 +
23.25 +void
23.26 +HField::hold(BytecodeEmitter &emitter_)
23.27 +{
23.28 + __ dup();
23.29 +}
23.30 +
23.31 +void
23.32 +HField::swapAndPick(BytecodeEmitter &emitter_)
23.33 +{
23.34 + // BASE VALUE
23.35 + __ swap(); // VALUE BASE
23.36 + __ pick2(); // VALUE BASE VALUE
23.37 +}
23.38 +
23.39 +void
23.40 +HField::store(BytecodeEmitter &emitter_)
23.41 +{
23.42 + __ setfield(index_, type());
23.43 +}
23.44 +
23.45 +void
23.46 +HField::load(BytecodeEmitter &emitter_)
23.47 +{
23.48 + __ getfield(index_, type());
23.49 +}
23.50 +
23.51 +bool
23.52 +HField::ref(BytecodeEmitter &emitter_)
23.53 +{
23.54 + return false;
23.55 +}
23.56 +
23.57 +void
23.58 HIRTranslator::visitLocal(HLocal *local)
23.59 {
23.60 local->bind(this, emitter_);
23.61 @@ -300,6 +341,13 @@
23.62 }
23.63
23.64 void
23.65 +HIRTranslator::visitField(HField *field)
23.66 +{
23.67 + field->bind(this, emitter_);
23.68 + field->load(emitter_);
23.69 +}
23.70 +
23.71 +void
23.72 HIRTranslator::visitGlobal(HGlobal *global)
23.73 {
23.74 global->bind(this, emitter_);
23.75 @@ -486,11 +534,6 @@
23.76
23.77 Local<ArrayType> type(zone_, ArrayType::cast(hir->type()));
23.78
23.79 - // Attach an actual map to the dependent type, in case it's a new
23.80 - // type.
23.81 - if (!ArrayMap::Attach(zone_, type))
23.82 - return;
23.83 -
23.84 // The dependent map is used for the opcode, but is not attached.
23.85 Local<ArrayMap> map(zone_, ArrayMap::NewDependent(zone_, type));
23.86 if (!map)
23.87 @@ -500,6 +543,12 @@
23.88 }
23.89
23.90 void
23.91 +HIRTranslator::visitImport(HImport *import)
23.92 +{
23.93 + __ import(import->index());
23.94 +}
23.95 +
23.96 +void
23.97 ke::EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir)
23.98 {
23.99 HIRTranslator translator(zone, emitter);
24.1 --- a/src/compiler/HIR.h Tue Jan 01 20:08:34 2013 -0800
24.2 +++ b/src/compiler/HIR.h Sun Jan 06 13:52:21 2013 -0800
24.3 @@ -31,6 +31,7 @@
24.4 _(Integer) \
24.5 _(Float) \
24.6 _(String) \
24.7 + _(Import) \
24.8 _(Array) \
24.9 _(Store) \
24.10 _(ToRef) \
24.11 @@ -39,6 +40,7 @@
24.12 _(Index) \
24.13 _(Local) \
24.14 _(Global) \
24.15 + _(Field) \
24.16 /* End LValues */ \
24.17 _(Unary) \
24.18 _(Binary) \
24.19 @@ -184,6 +186,24 @@
24.20 ScopedRoot<String> string_;
24.21 };
24.22
24.23 +class HImport : public HIR
24.24 +{
24.25 + public:
24.26 + HImport(AstNode *node, Type *type, unsigned index)
24.27 + : HIR(node, type),
24.28 + index_(index)
24.29 + {
24.30 + }
24.31 +
24.32 + DEFINE_HIR(Import);
24.33 + unsigned index() const {
24.34 + return index_;
24.35 + }
24.36 +
24.37 + private:
24.38 + unsigned index_;
24.39 +};
24.40 +
24.41 class HArray : public HIR
24.42 {
24.43 public:
24.44 @@ -319,6 +339,37 @@
24.45 HIR *right_;
24.46 };
24.47
24.48 +class HField : public HLValue
24.49 +{
24.50 + public:
24.51 + HField(AstNode *node, HIR *left, Type *type, unsigned index)
24.52 + : HLValue(node, type),
24.53 + base_(left),
24.54 + index_(index)
24.55 + {
24.56 + }
24.57 +
24.58 + DEFINE_HIR(Field);
24.59 +
24.60 + void bind(HIRVisitor *visitor, BytecodeEmitter &emitter_);
24.61 + void hold(BytecodeEmitter &emitter_);
24.62 + void swapAndPick(BytecodeEmitter &emitter_);
24.63 + void store(BytecodeEmitter &emitter_);
24.64 + void load(BytecodeEmitter &emitter_);
24.65 + bool ref(BytecodeEmitter &emitter_);
24.66 +
24.67 + HIR *base() const {
24.68 + return base_;
24.69 + }
24.70 + unsigned index() const {
24.71 + return index_;
24.72 + }
24.73 +
24.74 + private:
24.75 + HIR *base_;
24.76 + unsigned index_;
24.77 +};
24.78 +
24.79 class HGlobal : public HLValue
24.80 {
24.81 public:
25.1 --- a/src/compiler/NameBinding.cpp Tue Jan 01 20:08:34 2013 -0800
25.2 +++ b/src/compiler/NameBinding.cpp Sun Jan 06 13:52:21 2013 -0800
25.3 @@ -197,6 +197,7 @@
25.4 if (node->initialization())
25.5 node->initialization()->accept(this);
25.6 }
25.7 +
25.8 void visitEnumStatement(EnumStatement *node) {
25.9 Local<String> name(zone_, node->name());
25.10 Local<Type> type(zone_);
25.11 @@ -239,6 +240,7 @@
25.12 value++;
25.13 }
25.14 }
25.15 +
25.16 void visitFunctionStatement(FunctionStatement *node) {
25.17 // We create function types ahead of time, not for any particular
25.18 // reason. It makes things consistent with FunctionTypeStatement,
25.19 @@ -260,9 +262,6 @@
25.20 {
25.21 // We're in the global scope, for sure.
25.22 assert(env_->scope()->kind() == Scope::GLOBAL);
25.23 - GlobalScope *globals = (GlobalScope *)env_->scope();
25.24 - if (!globals->addPublic(sym))
25.25 - return;
25.26 }
25.27
25.28 node->setSymbol(sym);
25.29 @@ -298,9 +297,11 @@
25.30
25.31 node->setScopes(argEnv.scope(), localEnv.scope());
25.32 }
25.33 +
25.34 void visitStructureStatement(StructureStatement *node) {
25.35 assert(false);
25.36 }
25.37 +
25.38 void visiFunctionTypeStatementt(FunctionTypeStatement *node) {
25.39 assert(false);
25.40 }
25.41 @@ -492,73 +493,23 @@
25.42 static const int EVAL_ARRAY_SIZE = -1;
25.43 static const int DYNAMIC_ARRAY_SIZE = -2;
25.44
25.45 -class NameBinder : public AstVisitor
25.46 +class NameBinderBase : public AstVisitor
25.47 {
25.48 public:
25.49 - class AutoLinkScope
25.50 - {
25.51 - public:
25.52 - AutoLinkScope(AutoLinkScope **prevp, Scope *scope)
25.53 - : prevp_(prevp),
25.54 - prev_(*prevp),
25.55 - scope_(scope)
25.56 - {
25.57 - if (scope_) {
25.58 - *prevp_ = this;
25.59 - if (prev_)
25.60 - scope_->setParent(prev_->scope());
25.61 - }
25.62 - }
25.63 - ~AutoLinkScope() {
25.64 - if (scope_) {
25.65 - assert(*prevp_ == this);
25.66 - *prevp_ = prev_;
25.67 - }
25.68 - }
25.69 - Scope *scope() const {
25.70 - return scope_;
25.71 - }
25.72 -
25.73 - private:
25.74 - AutoLinkScope **prevp_;
25.75 - AutoLinkScope *prev_;
25.76 - Scope *scope_;
25.77 - };
25.78 -
25.79 - public:
25.80 - NameBinder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
25.81 + NameBinderBase(Zone *zone, CompileContext &cc, TranslationUnit *unit)
25.82 : zone_(zone),
25.83 pool_(zone->pool()),
25.84 cc_(cc),
25.85 - unit_(unit),
25.86 - link_(NULL)
25.87 + unit_(unit)
25.88 {
25.89 }
25.90
25.91 - void bind() {
25.92 - // Start with the import scope, and collect all imported names.
25.93 - AutoLinkScope importScope(&link_, unit_->importScope());
25.94
25.95 - for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
25.96 - unit_->tree()->imports()->at(i)->accept(this);
25.97 -
25.98 - // Next, enter the global scope and walk all statements.
25.99 - AutoLinkScope globalScope(&link_, unit_->globalScope());
25.100 - for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
25.101 - Statement *stmt = unit_->tree()->statements()->at(i);
25.102 - stmt->accept(this);
25.103 - }
25.104 - }
25.105 -
25.106 - void visitVariableDeclaration(VariableDeclaration *node) {
25.107 - // Bind the initializer before registering the declaration, so that we
25.108 - // can error on bogus initializers (new x = x).
25.109 - if (node->initialization())
25.110 - node->initialization()->accept(this);
25.111 -
25.112 + protected:
25.113 + Type *buildVariableType(VariableDeclaration *node) {
25.114 Local<Type> type(zone_, bindType(node->type(), node->quals()));
25.115 if (!type)
25.116 - return;
25.117 + return NULL;
25.118
25.119 // We don't allow array typedefs yet.
25.120 assert(!type->isArray());
25.121 @@ -567,7 +518,7 @@
25.122 int dims[MAX_ARRAY_DEPTH];
25.123 int levels = evaluateDimensions(node->pos(), type, node->dims(), dims);
25.124 if (levels < 0)
25.125 - return;
25.126 + return NULL;
25.127
25.128 // Do some extra inference based on the initializer, if present.
25.129 Expression *init = node->initialization();
25.130 @@ -577,7 +528,7 @@
25.131 ? ArrayType::cast(type)->contained()
25.132 : type);
25.133 if (!inferFixedArrayDimensions(init->toArrayLiteral(), contained, dims, levels))
25.134 - return;
25.135 + return NULL;
25.136 } else if (init->isStringLiteral()) {
25.137 dims[levels - 1] = init->toStringLiteral()->string()->length() + 1;
25.138 }
25.139 @@ -586,180 +537,13 @@
25.140 // If we got extra dimensions, we need to build a new type.
25.141 if (node->dims()) {
25.142 if ((type = buildArrayType(type, node->quals(), dims, node->dims()->length())) == NULL)
25.143 - return;
25.144 + return NULL;
25.145 }
25.146 }
25.147
25.148 - // If we're in global scope, and we received a |const| qualifier, then
25.149 - // we extend this to array references as well. This is to sort of mimic
25.150 - // SP1 functionality, but also means that you cannot have changeable
25.151 - // const pointers in global scope.
25.152 - if ((node->quals() & TypeQual_Const) &&
25.153 - type->isArray() &&
25.154 - link_->scope()->kind() == Scope::GLOBAL)
25.155 - {
25.156 - if ((type = zone_->types()->qualify(type, TypeQual_Const)) == NULL)
25.157 - return;
25.158 - }
25.159 -
25.160 - // If the node already has a symbol (meaning it was a global), then
25.161 - // we don't have to do anything more.
25.162 - if (node->sym()) {
25.163 - assert(node->sym()->scope()->kind() == Scope::GLOBAL);
25.164 - node->sym()->setType(type);
25.165 - return;
25.166 - }
25.167 -
25.168 - VariableSymbol *sym = new (pool_) VariableSymbol(link_->scope(), node->name(), node->pos(), type);
25.169 - node->setSymbol(sym);
25.170 -
25.171 - if (Symbol *other = link_->scope()->localLookup(sym->name())) {
25.172 - // Report, but allow errors to continue.
25.173 - cc_.reportError(sym->pos(), Message_RedeclaredName,
25.174 - sym->name()->chars(),
25.175 - other->pos().line,
25.176 - other->pos().col);
25.177 - return;
25.178 - }
25.179 -
25.180 - link_->scope()->addSymbol(sym);
25.181 - }
25.182 - void visitEnumStatement(EnumStatement *node) {
25.183 - }
25.184 - void visitFunctionStatement(FunctionStatement *node) {
25.185 - AutoLinkScope argScope(&link_, node->argScope());
25.186 - AutoLinkScope varScope(&link_, node->varScope());
25.187 -
25.188 - Local<FunctionType> type(zone_, node->sym()->type());
25.189 - if (!fillFunctionType(type, node->signature()))
25.190 - return;
25.191 -
25.192 - if (node->body())
25.193 - node->body()->accept(this);
25.194 - }
25.195 - void visitStructureStatement(StructureStatement *node) {
25.196 - assert(false);
25.197 - }
25.198 - void visitFunctionTypeStatement(FunctionTypeStatement *node) {
25.199 - assert(false);
25.200 + return type;
25.201 }
25.202
25.203 - void visitNameProxy(NameProxy *proxy) {
25.204 - Scope *scope = link_->scope();
25.205 - Symbol *sym = scope->lookup(proxy->name());
25.206 - if (!sym)
25.207 - cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
25.208 - proxy->bind(sym);
25.209 - }
25.210 - void visitAssignment(Assignment *node) {
25.211 - node->lvalue()->accept(this);
25.212 - node->expression()->accept(this);
25.213 - }
25.214 - void visitBinaryExpression(BinaryExpression *node) {
25.215 - node->left()->accept(this);
25.216 - node->right()->accept(this);
25.217 - }
25.218 - void visitReturnStatement(ReturnStatement *node) {
25.219 - node->expression()->accept(this);
25.220 - }
25.221 - void visitForStatement(ForStatement *node) {
25.222 - AutoLinkScope scope(&link_, node->scope());
25.223 -
25.224 - if (node->initialization())
25.225 - node->initialization()->accept(this);
25.226 - if (node->condition())
25.227 - node->condition()->accept(this);
25.228 - if (node->update())
25.229 - node->update()->accept(this);
25.230 - node->body()->accept(this);
25.231 - }
25.232 - void visitBlockStatement(BlockStatement *node) {
25.233 - AutoLinkScope scope(&link_, node->scope());
25.234 - for (size_t i = 0; i < node->statements()->length(); i++)
25.235 - node->statements()->at(i)->accept(this);
25.236 - }
25.237 - void visitIntegerLiteral(IntegerLiteral *node) {
25.238 - }
25.239 - void visitExpressionStatement(ExpressionStatement *node) {
25.240 - node->expression()->accept(this);
25.241 - }
25.242 - void visitCallExpression(CallExpression *node) {
25.243 - node->callee()->accept(this);
25.244 - for (size_t i = 0; i < node->arguments()->length(); i++)
25.245 - node->arguments()->at(i)->accept(this);
25.246 - }
25.247 - void visitIfStatement(IfStatement *node) {
25.248 - node->condition()->accept(this);
25.249 - node->ifTrue()->accept(this);
25.250 - if (node->ifFalse())
25.251 - node->ifFalse()->accept(this);
25.252 - }
25.253 - void visitIndexExpression(IndexExpression *node) {
25.254 - node->left()->accept(this);
25.255 - node->right()->accept(this);
25.256 - }
25.257 - void visitFloatLiteral(FloatLiteral *node) {
25.258 - }
25.259 - void visitWhileStatement(WhileStatement *node) {
25.260 - node->condition()->accept(this);
25.261 - node->body()->accept(this);
25.262 - }
25.263 - void visitBreakStatement(BreakStatement *node) {
25.264 - }
25.265 - void visitContinueStatement(ContinueStatement *node) {
25.266 - }
25.267 - void visitStringLiteral(StringLiteral *node) {
25.268 - }
25.269 - void visitIncDecExpression(IncDecExpression *node) {
25.270 - node->expression()->accept(this);
25.271 - }
25.272 - void visitUnaryExpression(UnaryExpression *node) {
25.273 - if (node->tag())
25.274 - node->tag()->accept(this);
25.275 - node->expression()->accept(this);
25.276 - }
25.277 - void visitTernaryExpression(TernaryExpression *node) {
25.278 - node->condition()->accept(this);
25.279 - node->left()->accept(this);
25.280 - node->right()->accept(this);
25.281 - }
25.282 - void visitBooleanLiteral(BooleanLiteral *node) {
25.283 - }
25.284 - void visitFieldExpression(FieldExpression *node) {
25.285 - node->left()->accept(this);
25.286 - }
25.287 - void visitSwitchStatement(SwitchStatement *node) {
25.288 - node->expression()->accept(this);
25.289 - node->defaultCase()->accept(this);
25.290 - for (size_t i = 0; i < node->cases()->length(); i++) {
25.291 - // We don't test case expressions because they are literals.
25.292 - Case *c = node->cases()->at(i);
25.293 - c->statement()->accept(this);
25.294 - }
25.295 - }
25.296 - void visitArrayLiteral(ArrayLiteral *node) {
25.297 - for (size_t i = 0; i < node->expressions()->length(); i++)
25.298 - node->expressions()->at(i)->accept(this);
25.299 - }
25.300 - void visitImportStatement(ImportStatement *node) {
25.301 - if (node->suffix() == TOK_STAR) {
25.302 - // Import every name.
25.303 - assert(false);
25.304 - } else {
25.305 - assert(false);
25.306 -#if 0
25.307 - GlobalScope *other = node->source()->globalScope();
25.308 - Symbol *sym = other->findPublic(node->name());
25.309 - if (!sym) {
25.310 - cc_.reportError(node->pos(), Message_CannotResolveImport, node->name()->chars());
25.311 - return;
25.312 - }
25.313 - link_->scope()->addSymbol(sym);
25.314 -#endif
25.315 - }
25.316 - }
25.317 -
25.318 - private:
25.319 int evaluateDimensions(const SourcePosition &pos, Handle<Type> typeArg, ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH]) {
25.320 unsigned level = 0;
25.321 Local<Type> type(zone_, typeArg);
25.322 @@ -967,11 +751,344 @@
25.323 return zone_->types()->qualify(type, quals);
25.324 }
25.325
25.326 - private:
25.327 + protected:
25.328 Zone *zone_;
25.329 PoolAllocator &pool_;
25.330 CompileContext &cc_;
25.331 TranslationUnit *unit_;
25.332 +};
25.333 +
25.334 +class GlobalBuilder : public NameBinderBase
25.335 +{
25.336 + public:
25.337 + GlobalBuilder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
25.338 + : NameBinderBase(zone, cc, unit)
25.339 + {
25.340 + }
25.341 +
25.342 + Struct *build() {
25.343 + for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
25.344 + unit_->tree()->imports()->at(i)->accept(this);
25.345 +
25.346 + // Next, enter the global scope and walk all statements.
25.347 + for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
25.348 + Statement *stmt = unit_->tree()->statements()->at(i);
25.349 + stmt->accept(this);
25.350 + }
25.351 +
25.352 + Local<FixedArray> descs(zone_, FixedArray::New(zone_, descriptors_.length(), Heap::Tenure_Old));
25.353 + if (!descs)
25.354 + return NULL;
25.355 +
25.356 + for (unsigned i = 0; i < descriptors_.length(); i++)
25.357 + descs->set(zone_, i, *descriptors_[i]);
25.358 +
25.359 + Local<String> name(zone_, unit_->module()->name());
25.360 + Local<StructType> type(zone_, StructType::New(zone_, name, descs));
25.361 + if (!type)
25.362 + return NULL;
25.363 +
25.364 + Local<StructMap> map(zone_, type->newMap());
25.365 + return Struct::New(zone_, map, Heap::Tenure_Old);
25.366 + }
25.367 +
25.368 + void visitEnumStatement(EnumStatement *stmt) {
25.369 + }
25.370 +
25.371 + void visitNameProxy(NameProxy *proxy) {
25.372 + // Don't report errors here, since we'll report them later.
25.373 + Scope *scope = unit_->globalScope();
25.374 + Symbol *sym = scope->lookup(proxy->name());
25.375 + proxy->bind(sym);
25.376 + }
25.377 +
25.378 + void visitFunctionStatement(FunctionStatement *node) {
25.379 + Local<FunctionType> type(zone_, node->sym()->type());
25.380 + if (!fillFunctionType(type, node->signature()))
25.381 + return;
25.382 +
25.383 + unsigned offset;
25.384 + if (!builder_.add(type, &offset))
25.385 + return;
25.386 +
25.387 + Descriptor::Visibility visibility = (node->token() == TOK_NATIVE || node->token() == TOK_FORWARD)
25.388 + ? Descriptor::Public
25.389 + : Descriptor::Private;
25.390 +
25.391 + Descriptor *desc = Descriptor::New(zone_, node->name(), type, visibility);
25.392 + if (!desc)
25.393 + return;
25.394 + if (!descriptors_.append(new (pool_) ScopedRoot<Descriptor>(desc)))
25.395 + return;
25.396 + }
25.397 +
25.398 + void visitVariableDeclaration(VariableDeclaration *node) {
25.399 + Local<Type> type(zone_, buildVariableType(node));
25.400 + if (!type)
25.401 + return;
25.402 +
25.403 + // If we're in global scope, and we received a |const| qualifier, then
25.404 + // we extend this to array references as well. This is to sort of mimic
25.405 + // SP1 functionality, but also means that you cannot have changeable
25.406 + // const pointers in global scope.
25.407 + if ((node->quals() & TypeQual_Const) && type->isArray()) {
25.408 + if ((type = zone_->types()->qualify(type, TypeQual_Const)) == NULL)
25.409 + return;
25.410 + }
25.411 +
25.412 + node->sym()->setType(type);
25.413 +
25.414 + unsigned offset;
25.415 + if (!builder_.add(type, &offset))
25.416 + return;
25.417 +
25.418 + Descriptor *desc = Descriptor::New(zone_, node->name(), type, Descriptor::Private);
25.419 + if (!desc)
25.420 + return;
25.421 + if (!descriptors_.append(new (pool_) ScopedRoot<Descriptor>(desc)))
25.422 + return;
25.423 + }
25.424 +
25.425 + void visitImportStatement(ImportStatement *node) {
25.426 + // Eventually we'll handle |from| style imports as well.
25.427 + {
25.428 + PathComponent *path = node->path();
25.429 + while (path->next)
25.430 + path = path->next;
25.431 +
25.432 + // Imports automatically go into the importScope. For now, we
25.433 + // error if there are any duplicate symbols entered into the
25.434 + // importScope.
25.435 + if (Symbol *sym = unit_->importScope()->localLookup(path->name)) {
25.436 + cc_.reportError(node->pos(), Message_DuplicateImport, path->name->chars());
25.437 + return;
25.438 + }
25.439 +
25.440 + Local<Type> type(zone_, zone_->types()->getImportable());
25.441 + ImportSymbol *sym = new (pool_) ImportSymbol(unit_->importScope(), path->name, node->pos(), type, node->importIndex());
25.442 + if (!unit_->importScope()->addSymbol(sym))
25.443 + return;
25.444 + }
25.445 + }
25.446 +
25.447 + private:
25.448 + StructureBufferBuilder builder_;
25.449 + Vector<ScopedRoot<Descriptor> *> descriptors_;
25.450 +};
25.451 +
25.452 +class NameBinder : public NameBinderBase
25.453 +{
25.454 + public:
25.455 + class AutoLinkScope
25.456 + {
25.457 + public:
25.458 + AutoLinkScope(AutoLinkScope **prevp, Scope *scope)
25.459 + : prevp_(prevp),
25.460 + prev_(*prevp),
25.461 + scope_(scope)
25.462 + {
25.463 + if (scope_) {
25.464 + *prevp_ = this;
25.465 + if (prev_)
25.466 + scope_->setParent(prev_->scope());
25.467 + }
25.468 + }
25.469 + ~AutoLinkScope() {
25.470 + if (scope_) {
25.471 + assert(*prevp_ == this);
25.472 + *prevp_ = prev_;
25.473 + }
25.474 + }
25.475 + Scope *scope() const {
25.476 + return scope_;
25.477 + }
25.478 +
25.479 + private:
25.480 + AutoLinkScope **prevp_;
25.481 + AutoLinkScope *prev_;
25.482 + Scope *scope_;
25.483 + };
25.484 +
25.485 + public:
25.486 + NameBinder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
25.487 + : NameBinderBase(zone, cc, unit),
25.488 + link_(NULL)
25.489 + {
25.490 + }
25.491 +
25.492 + void bind() {
25.493 + // Start with the import scope, and collect all imported names.
25.494 + AutoLinkScope importScope(&link_, unit_->importScope());
25.495 +
25.496 + for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
25.497 + unit_->tree()->imports()->at(i)->accept(this);
25.498 +
25.499 + // Next, enter the global scope and walk all statements.
25.500 + AutoLinkScope globalScope(&link_, unit_->globalScope());
25.501 + for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
25.502 + Statement *stmt = unit_->tree()->statements()->at(i);
25.503 + stmt->accept(this);
25.504 + }
25.505 + }
25.506 +
25.507 + void visitVariableDeclaration(VariableDeclaration *node) {
25.508 + // Bind the initializer before registering the declaration, so that we
25.509 + // can error on bogus initializers (new x = x).
25.510 + if (node->initialization())
25.511 + node->initialization()->accept(this);
25.512 +
25.513 + // If the node already has a symbol (meaning it was a global), then
25.514 + // we don't have to do anything more.
25.515 + if (node->sym())
25.516 + return;
25.517 +
25.518 + Local<Type> type(zone_, buildVariableType(node));
25.519 + if (!type)
25.520 + return;
25.521 +
25.522 + VariableSymbol *sym = new (pool_) VariableSymbol(link_->scope(), node->name(), node->pos(), type);
25.523 + node->setSymbol(sym);
25.524 +
25.525 + if (Symbol *other = link_->scope()->localLookup(sym->name())) {
25.526 + // Report, but allow errors to continue.
25.527 + cc_.reportError(sym->pos(), Message_RedeclaredName,
25.528 + sym->name()->chars(),
25.529 + other->pos().line,
25.530 + other->pos().col);
25.531 + return;
25.532 + }
25.533 +
25.534 + link_->scope()->addSymbol(sym);
25.535 + }
25.536 + void visitEnumStatement(EnumStatement *node) {
25.537 + }
25.538 + void visitFunctionStatement(FunctionStatement *node) {
25.539 + AutoLinkScope argScope(&link_, node->argScope());
25.540 + AutoLinkScope varScope(&link_, node->varScope());
25.541 +
25.542 + // If the function is in the global scope, we've already computed its
25.543 + // type.
25.544 + if (node->sym()->scope()->kind() != Scope::GLOBAL) {
25.545 + Local<FunctionType> type(zone_, node->sym()->type());
25.546 + if (!fillFunctionType(type, node->signature()))
25.547 + return;
25.548 + }
25.549 +
25.550 + if (node->body())
25.551 + node->body()->accept(this);
25.552 + }
25.553 + void visitStructureStatement(StructureStatement *node) {
25.554 + assert(false);
25.555 + }
25.556 + void visitFunctionTypeStatement(FunctionTypeStatement *node) {
25.557 + assert(false);
25.558 + }
25.559 +
25.560 + void visitNameProxy(NameProxy *proxy) {
25.561 + // We could have already bound globals.
25.562 + if (proxy->sym())
25.563 + return;
25.564 +
25.565 + Scope *scope = link_->scope();
25.566 + Symbol *sym = scope->lookup(proxy->name());
25.567 + if (!sym)
25.568 + cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
25.569 + proxy->bind(sym);
25.570 + }
25.571 + void visitAssignment(Assignment *node) {
25.572 + node->lvalue()->accept(this);
25.573 + node->expression()->accept(this);
25.574 + }
25.575 + void visitBinaryExpression(BinaryExpression *node) {
25.576 + node->left()->accept(this);
25.577 + node->right()->accept(this);
25.578 + }
25.579 + void visitReturnStatement(ReturnStatement *node) {
25.580 + node->expression()->accept(this);
25.581 + }
25.582 + void visitForStatement(ForStatement *node) {
25.583 + AutoLinkScope scope(&link_, node->scope());
25.584 +
25.585 + if (node->initialization())
25.586 + node->initialization()->accept(this);
25.587 + if (node->condition())
25.588 + node->condition()->accept(this);
25.589 + if (node->update())
25.590 + node->update()->accept(this);
25.591 + node->body()->accept(this);
25.592 + }
25.593 + void visitBlockStatement(BlockStatement *node) {
25.594 + AutoLinkScope scope(&link_, node->scope());
25.595 + for (size_t i = 0; i < node->statements()->length(); i++)
25.596 + node->statements()->at(i)->accept(this);
25.597 + }
25.598 + void visitIntegerLiteral(IntegerLiteral *node) {
25.599 + }
25.600 + void visitExpressionStatement(ExpressionStatement *node) {
25.601 + node->expression()->accept(this);
25.602 + }
25.603 + void visitCallExpression(CallExpression *node) {
25.604 + node->callee()->accept(this);
25.605 + for (size_t i = 0; i < node->arguments()->length(); i++)
25.606 + node->arguments()->at(i)->accept(this);
25.607 + }
25.608 + void visitIfStatement(IfStatement *node) {
25.609 + node->condition()->accept(this);
25.610 + node->ifTrue()->accept(this);
25.611 + if (node->ifFalse())
25.612 + node->ifFalse()->accept(this);
25.613 + }
25.614 + void visitIndexExpression(IndexExpression *node) {
25.615 + node->left()->accept(this);
25.616 + node->right()->accept(this);
25.617 + }
25.618 + void visitFloatLiteral(FloatLiteral *node) {
25.619 + }
25.620 + void visitWhileStatement(WhileStatement *node) {
25.621 + node->condition()->accept(this);
25.622 + node->body()->accept(this);
25.623 + }
25.624 + void visitBreakStatement(BreakStatement *node) {
25.625 + }
25.626 + void visitContinueStatement(ContinueStatement *node) {
25.627 + }
25.628 + void visitStringLiteral(StringLiteral *node) {
25.629 + }
25.630 + void visitIncDecExpression(IncDecExpression *node) {
25.631 + node->expression()->accept(this);
25.632 + }
25.633 + void visitUnaryExpression(UnaryExpression *node) {
25.634 + if (node->tag())
25.635 + node->tag()->accept(this);
25.636 + node->expression()->accept(this);
25.637 + }
25.638 + void visitTernaryExpression(TernaryExpression *node) {
25.639 + node->condition()->accept(this);
25.640 + node->left()->accept(this);
25.641 + node->right()->accept(this);
25.642 + }
25.643 + void visitBooleanLiteral(BooleanLiteral *node) {
25.644 + }
25.645 + void visitFieldExpression(FieldExpression *node) {
25.646 + node->left()->accept(this);
25.647 + }
25.648 + void visitSwitchStatement(SwitchStatement *node) {
25.649 + node->expression()->accept(this);
25.650 + node->defaultCase()->accept(this);
25.651 + for (size_t i = 0; i < node->cases()->length(); i++) {
25.652 + // We don't test case expressions because they are literals.
25.653 + Case *c = node->cases()->at(i);
25.654 + c->statement()->accept(this);
25.655 + }
25.656 + }
25.657 + void visitArrayLiteral(ArrayLiteral *node) {
25.658 + for (size_t i = 0; i < node->expressions()->length(); i++)
25.659 + node->expressions()->at(i)->accept(this);
25.660 + }
25.661 + void visitImportStatement(ImportStatement *node) {
25.662 + }
25.663 +
25.664 + private:
25.665 AutoLinkScope *link_;
25.666 };
25.667
25.668 @@ -979,6 +1096,18 @@
25.669 ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
25.670 {
25.671 AutoEnterCompileContext enter(cc, unit);
25.672 +
25.673 + // Because of the way globals work in Pawn, we need a precursor step to
25.674 + // actually enter global symbols into the global struct. They're already
25.675 + // in the global symbol table, so we know they won't clash. This process
25.676 + // also binds any remaining types on global variables.
25.677 + GlobalBuilder builder(zone, cc, unit);
25.678 + Local<Struct> globals(zone, builder.build());
25.679 + if (!globals || unit->failed())
25.680 + return;
25.681 +
25.682 + unit->module()->setGlobals(globals);
25.683 +
25.684 NameBinder binder(zone, cc, unit);
25.685 binder.bind();
25.686 }
26.1 --- a/src/compiler/Parser.cpp Tue Jan 01 20:08:34 2013 -0800
26.2 +++ b/src/compiler/Parser.cpp Sun Jan 06 13:52:21 2013 -0800
26.3 @@ -1236,9 +1236,7 @@
26.4 static inline ScopedRoot<T> *
26.5 NewScopedRoot(PoolAllocator &pool, Handle<T> obj)
26.6 {
26.7 - ScopedRoot<T> *root = pool.alloc<ScopedRoot<T> >();
26.8 - new (root) ScopedRoot<T>(obj);
26.9 - return root;
26.10 + return new (pool) ScopedRoot<T>(obj);
26.11 }
26.12
26.13 ImportStatement *
26.14 @@ -1246,7 +1244,7 @@
26.15 {
26.16 SourcePosition pos = scanner_.begin();
26.17
26.18 - // import ::= import_path ("." "*")?
26.19 + // import ::= import_path
26.20 // import_path ::= name |
26.21 // name "." import_path
26.22
26.23 @@ -1259,11 +1257,6 @@
26.24
26.25 TokenKind suffix = TOK_NONE;
26.26 while (match(TOK_DOT)) {
26.27 - if (match(TOK_STAR)) {
26.28 - suffix = TOK_STAR;
26.29 - break;
26.30 - }
26.31 -
26.32 if ((name = expectName()) == NULL)
26.33 return NULL;
26.34
26.35 @@ -1271,7 +1264,7 @@
26.36 current = current->next;
26.37 }
26.38
26.39 - return new (pool_) ImportStatement(pos, root, suffix);
26.40 + return new (pool_) ImportStatement(pos, root);
26.41 }
26.42
26.43 Statement *
27.1 --- a/src/compiler/Scopes.cpp Tue Jan 01 20:08:34 2013 -0800
27.2 +++ b/src/compiler/Scopes.cpp Sun Jan 06 13:52:21 2013 -0800
27.3 @@ -168,47 +168,6 @@
27.4 return scope;
27.5 }
27.6
27.7 -bool
27.8 -GlobalScope::addPublic(Symbol *sym)
27.9 -{
27.10 - return publics_.append(sym);
27.11 -}
27.12 -
27.13 -Symbol *
27.14 -GlobalScope::findPublic(Handle<String> name)
27.15 -{
27.16 - for (size_t i = 0; i < publics_.length(); i++) {
27.17 - if (publics_[i]->name() == name)
27.18 - return publics_[i];
27.19 - }
27.20 - return NULL;
27.21 -}
27.22 -
27.23 -Struct *
27.24 -GlobalScope::build(Zone *zone)
27.25 -{
27.26 - Local<FixedArray> descriptors(zone, FixedArray::New(zone, names_.length(), Heap::Tenure_Old));
27.27 -
27.28 - for (size_t i = 0; i < names_.length(); i++) {
27.29 - Handle<String> name = names_[i]->name();
27.30 - Handle<Type> type = names_[i]->type();
27.31 - assert(type);
27.32 -
27.33 - Local<Descriptor> desc(zone, Descriptor::New(zone, name, type));
27.34 - if (!desc)
27.35 - return NULL;
27.36 -
27.37 - descriptors->set(zone, i, desc);
27.38 - }
27.39 -
27.40 - Local<StructType> type(zone, StructType::New(zone, Handle<String>::Null(), descriptors));
27.41 - if (!type)
27.42 - return NULL;
27.43 -
27.44 - Local<StructMap> map(zone, type->newMap());
27.45 - return Struct::New(zone, map, Heap::Tenure_Old);
27.46 -}
27.47 -
27.48 ImportScope::ImportScope(PoolAllocator &pool)
27.49 : Scope(pool, Scope::IMPORT, NULL)
27.50 {
28.1 --- a/src/compiler/Scopes.h Tue Jan 01 20:08:34 2013 -0800
28.2 +++ b/src/compiler/Scopes.h Sun Jan 06 13:52:21 2013 -0800
28.3 @@ -101,15 +101,8 @@
28.4 public:
28.5 static GlobalScope *New(PoolAllocator &pool, ImportScope *parent);
28.6
28.7 - bool addPublic(Symbol *symbol);
28.8 - Symbol *findPublic(Handle<String> name);
28.9 - Struct *build(Zone *zone);
28.10 -
28.11 private:
28.12 GlobalScope(PoolAllocator &pool, ImportScope *parent);
28.13 -
28.14 - private:
28.15 - PoolList<Symbol *> publics_;
28.16 };
28.17
28.18 class ImportScope : public Scope
29.1 --- a/src/compiler/SemanticAnalysis.cpp Tue Jan 01 20:08:34 2013 -0800
29.2 +++ b/src/compiler/SemanticAnalysis.cpp Sun Jan 06 13:52:21 2013 -0800
29.3 @@ -93,11 +93,6 @@
29.4 stmt->accept(this);
29.5 }
29.6
29.7 - Local<Struct> globals(zone_, unit_->globalScope()->build(zone_));
29.8 - if (!globals)
29.9 - return;
29.10 - unit_->module()->setGlobals(globals);
29.11 -
29.12 Local<Code> code(zone_, __ finish());
29.13 if (!code)
29.14 return;
29.15 @@ -448,7 +443,7 @@
29.16 __ float_(0);
29.17 } else if (type->isArray()) {
29.18 Local<ArrayType> atype(zone_, ArrayType::cast(type));
29.19 - Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, atype));
29.20 + Local<ArrayMap> map(zone_, atype->newMap());
29.21 if (!map)
29.22 return;
29.23
29.24 @@ -570,6 +565,13 @@
29.25 Symbol *sym = proxy->sym();
29.26
29.27 switch (sym->kind()) {
29.28 + case Symbol::kImport:
29.29 + {
29.30 + ImportSymbol *import = sym->toImport();
29.31 + hir_ = new (pool_) HImport(proxy, sym->type(), import->index());
29.32 + break;
29.33 + }
29.34 +
29.35 case Symbol::kConstant:
29.36 {
29.37 ConstantSymbol *val = sym->toConstant();
29.38 @@ -936,7 +938,7 @@
29.39 // Transform the string literal into an array literal. We give it the
29.40 // type of the left-hand side. The constness of the destination type
29.41 // will determine whether HArray duplicates it or not.
29.42 - Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, actual));
29.43 + Local<ArrayMap> map(zone_, actual->newMap());
29.44 if (!map)
29.45 return NULL;
29.46
29.47 @@ -1066,6 +1068,10 @@
29.48 {
29.49 Local<Type> from(zone_, hir->type());
29.50
29.51 + // If the source is *ever* an importable, we just fail.
29.52 + if (from->isImportable())
29.53 + return typeFailure(hir->node()->pos(), from, to);
29.54 +
29.55 if (from->isInt32() && to->isFloat())
29.56 return new (pool_) HConvert(hir->node(), to, OP_CVT_I2F, hir);
29.57 if (from->isInt32() && to->isBool())
29.58 @@ -1218,6 +1224,70 @@
29.59 }
29.60 }
29.61
29.62 +void
29.63 +SemanticAnalysis::import(HIR *hir, FieldExpression *node)
29.64 +{
29.65 + // Note that we don't care if the hir type is "importable", since we
29.66 + // can only do anything if the important has a constant binding.
29.67 + unsigned index = hir->toImport()->index();
29.68 + Local<Importable> importable(zone_, unit_->module()->getImportAt(index));
29.69 +
29.70 + if (importable->isPackage()) {
29.71 + // Look at what's already loaded and see if anything exists. We
29.72 + // can't create stuff on-demand here since it's too late to add
29.73 + // new translation units to the CompileContext.
29.74 + Local<Package> package(zone_, Package::cast(importable));
29.75 + Local<Importable> found(zone_, package->import(node->field()));
29.76 + if (!found) {
29.77 + cc_.reportError(node->pos(), Message_PackageDoesNotHaveMember, node->field()->chars());
29.78 + return;
29.79 + }
29.80 +
29.81 + // If we did find something, make sure it is in our import list.
29.82 + // If we didn't explicitly import it, we have no right to use it.
29.83 + for (index = 0; index < unit_->module()->imports(); index++) {
29.84 + if (unit_->module()->getImportAt(index) == importable)
29.85 + break;
29.86 + }
29.87 +
29.88 + if (index == unit_->module()->imports()) {
29.89 + cc_.reportError(node->pos(), Message_ImportWasNeverImported, node->field()->chars());
29.90 + return;
29.91 + }
29.92 +
29.93 + // Just create a new HImport.
29.94 + hir_ = new (pool_) HImport(node, hir->type(), index);
29.95 + } else {
29.96 + // Modules can never have sub-modules or sub-packages.
29.97 + unsigned index;
29.98 + Local<Module> module(zone_, Module::cast(importable));
29.99 + Local<StructMap> map(zone_, module->globals()->map());
29.100 + Local<Descriptor> desc(zone_, map->type()->lookupField(node->field(), &index));
29.101 + if (!desc) {
29.102 + cc_.reportError(node->pos(), Message_FieldNotFound, node->field()->chars());
29.103 + return;
29.104 + }
29.105 + hir_ = new (pool_) HField(node, hir, desc->type(), index);
29.106 + }
29.107 +}
29.108 +
29.109 +void
29.110 +SemanticAnalysis::visitFieldExpression(FieldExpression *node)
29.111 +{
29.112 + HIR *hir = eval(node->left());
29.113 + if (!hir)
29.114 + return;
29.115 +
29.116 + if (hir->isImport()) {
29.117 + import(hir, node);
29.118 + return;
29.119 + }
29.120 +
29.121 + char name[255];
29.122 + cc_.reportError(node->pos(), Message_InvalidFieldExpression,
29.123 + GetTypeName(hir->type(), name, sizeof(name)));
29.124 +}
29.125 +
29.126 static inline TokenKind
29.127 ToCompare(Expression *expr)
29.128 {
30.1 --- a/src/compiler/SemanticAnalysis.h Tue Jan 01 20:08:34 2013 -0800
30.2 +++ b/src/compiler/SemanticAnalysis.h Sun Jan 06 13:52:21 2013 -0800
30.3 @@ -67,6 +67,7 @@
30.4 void visitStringLiteral(StringLiteral *node);
30.5 void visitUnaryExpression(UnaryExpression *node);
30.6 void visitBooleanLiteral(BooleanLiteral *node);
30.7 + void visitFieldExpression(FieldExpression *node);
30.8 #if 0
30.9 void visitFunctionTypeStatement(FunctionTypeStatement *node);
30.10 void visitImportStatement(ImportStatement *node);
30.11 @@ -74,12 +75,12 @@
30.12 void visitSwitchStatement(SwitchStatement *node);
30.13
30.14 void visitTernaryExpression(TernaryExpression *node);
30.15 - void visitFieldExpression(FieldExpression *node);
30.16 void visitArrayLiteral(ArrayLiteral *node);
30.17 #endif
30.18
30.19 private:
30.20 bool checkArgumentCount(Handle<FunctionType> type, unsigned actual);
30.21 + void import(HIR *hir, FieldExpression *node);
30.22
30.23 private:
30.24 enum CoercionKind {
31.1 --- a/src/compiler/Symbols.h Tue Jan 01 20:08:34 2013 -0800
31.2 +++ b/src/compiler/Symbols.h Sun Jan 06 13:52:21 2013 -0800
31.3 @@ -38,8 +38,8 @@
31.4 _(Constant) \
31.5 /* A named type (class struct, typedef, etc) produces a TypeSymbol. */ \
31.6 _(Type) \
31.7 - /* // A module import produces a ModuleSymbol. */ \
31.8 - _(Module)
31.9 + /* An import name. */ \
31.10 + _(Import)
31.11
31.12 #define _(name) class name##Symbol;
31.13 SYMBOL_KINDS(_)
31.14 @@ -208,6 +208,28 @@
31.15 BoxedPrimitive value_;
31.16 };
31.17
31.18 +class ImportSymbol : public Symbol
31.19 +{
31.20 + public:
31.21 + ImportSymbol(Scope *scope, Handle<String> name, const SourcePosition &pos, Handle<Type> type,
31.22 + unsigned index)
31.23 + : Symbol(scope, name, pos),
31.24 + index_(index)
31.25 + {
31.26 + type_ = type;
31.27 + }
31.28 +
31.29 + Kind kind() const {
31.30 + return kImport;
31.31 + }
31.32 + unsigned index() const {
31.33 + return index_;
31.34 + }
31.35 +
31.36 + private:
31.37 + unsigned index_;
31.38 +};
31.39 +
31.40 }
31.41
31.42 #endif // _include_sp2_symbol_h_
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/tests/basic/import-sysroot-select.out Sun Jan 06 13:52:21 2013 -0800
32.3 @@ -0,0 +1,1 @@
32.4 +5 is 5.000000
33.1 --- a/tests/basic/import-sysroot-select.sp Tue Jan 01 20:08:34 2013 -0800
33.2 +++ b/tests/basic/import-sysroot-select.sp Sun Jan 06 13:52:21 2013 -0800
33.3 @@ -1,5 +1,3 @@
33.4 -import shell;
33.5 -import shell;
33.6 import shell;
33.7
33.8 public main()
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/tests/basic/shell.sp Sun Jan 06 13:52:21 2013 -0800
34.3 @@ -0,0 +1,3 @@
34.4 +native PrintNum(num);
34.5 +native PrintString(const char:text[]);
34.6 +native PrintFloat(float:f);
35.1 --- a/tests/shell.sp Tue Jan 01 20:08:34 2013 -0800
35.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
35.3 @@ -1,5 +0,0 @@
35.4 -native PrintNum(num);
35.5 -
35.6 -native PrintString(const char:text[]);
35.7 -
35.8 -native PrintFloat(float:f);