Implement |from x import *| syntax for modules.
Implement |from x import *| syntax for modules.
1.1 --- a/src/FixedArray.cpp Sun Jan 06 13:56:56 2013 -0800
1.2 +++ b/src/FixedArray.cpp Sat Jan 12 16:13:46 2013 -0800
1.3 @@ -1,19 +1,19 @@
1.4 /*
1.5 * Copyright (C) 2012 David Anderson
1.6 *
1.7 - * This file is part of JITCraft.
1.8 + * This file is part of SourcePawn.
1.9 *
1.10 - * JITCraft is free software: you can redistribute it and/or modify it under
1.11 + * SourcePawn is free software: you can redistribute it and/or modify it under
1.12 * the terms of the GNU General Public License as published by the Free
1.13 * Software Foundation, either version 3 of the License, or (at your option)
1.14 * any later version.
1.15 *
1.16 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
1.17 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
1.18 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.19 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.20 *
1.21 * You should have received a copy of the GNU General Public License along with
1.22 - * JITCraft. If not, see http://www.gnu.org/licenses/.
1.23 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
1.24 */
1.25 #include <limits.h>
1.26 #include <string.h>
2.1 --- a/src/Messages.tbl Sun Jan 06 13:56:56 2013 -0800
2.2 +++ b/src/Messages.tbl Sat Jan 12 16:13:46 2013 -0800
2.3 @@ -90,4 +90,5 @@
2.4 MSG(InvalidFieldExpression, TypeError, "type '%s' does not have any fields")
2.5 MSG(PackageDoesNotHaveMember, TypeError, "package does not have member '%s' (check imports)")
2.6 MSG(ImportWasNeverImported, TypeError, "'%s' was never imported")
2.7 -MSG(FieldNotFound, TypeError, "field '%s' not found")
2.8 \ No newline at end of file
2.9 +MSG(FieldNotFound, TypeError, "field '%s' not found")
2.10 +MSG(BadImportFrom, TypeError, "expected '*' or <name>")
2.11 \ No newline at end of file
3.1 --- a/src/Reference.h Sun Jan 06 13:56:56 2013 -0800
3.2 +++ b/src/Reference.h Sat Jan 12 16:13:46 2013 -0800
3.3 @@ -1,19 +1,19 @@
3.4 /*
3.5 * Copyright (C) 2012 David Anderson
3.6 *
3.7 - * This file is part of JITCraft.
3.8 + * This file is part of SourcePawn.
3.9 *
3.10 - * JITCraft is free software: you can redistribute it and/or modify it under
3.11 + * SourcePawn is free software: you can redistribute it and/or modify it under
3.12 * the terms of the GNU General Public License as published by the Free
3.13 * Software Foundation, either version 3 of the License, or (at your option)
3.14 * any later version.
3.15 *
3.16 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
3.17 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
3.18 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
3.19 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
3.20 *
3.21 * You should have received a copy of the GNU General Public License along with
3.22 - * JITCraft. If not, see http://www.gnu.org/licenses/.
3.23 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
3.24 */
3.25 #ifndef _include_jitcraft_reference_h_
3.26 #define _include_jitcraft_reference_h_
4.1 --- a/src/Types.cpp Sun Jan 06 13:56:56 2013 -0800
4.2 +++ b/src/Types.cpp Sat Jan 12 16:13:46 2013 -0800
4.3 @@ -205,8 +205,9 @@
4.4 }
4.5
4.6 Descriptor *
4.7 -StructType::lookupField(Handle<String> name, unsigned *index)
4.8 +StructType::lookupField(String *name, unsigned *index)
4.9 {
4.10 + // :TODO: assert no GC
4.11 for (unsigned i = 0; i < fields_->length(); i++) {
4.12 Descriptor *desc = Descriptor::cast(fields_->at(i));
4.13 if (desc->name() == name) {
5.1 --- a/src/Types.h Sun Jan 06 13:56:56 2013 -0800
5.2 +++ b/src/Types.h Sat Jan 12 16:13:46 2013 -0800
5.3 @@ -377,7 +377,7 @@
5.4 assert(isStruct());
5.5 return fields_;
5.6 }
5.7 - Descriptor *lookupField(Handle<String> name, unsigned *index = NULL);
5.8 + Descriptor *lookupField(String *name, unsigned *index = NULL);
5.9
5.10 // Objects of this type can be created with this cached map.
5.11 StructMap *newMap() {
6.1 --- a/src/compiler/AST.h Sun Jan 06 13:56:56 2013 -0800
6.2 +++ b/src/compiler/AST.h Sat Jan 12 16:13:46 2013 -0800
6.3 @@ -1086,9 +1086,10 @@
6.4 class ImportStatement : public Statement
6.5 {
6.6 public:
6.7 - ImportStatement(const SourcePosition &pos, PathComponent *path)
6.8 + ImportStatement(const SourcePosition &pos, PathComponent *path, NameList *names)
6.9 : Statement(pos),
6.10 - path_(path)
6.11 + path_(path),
6.12 + names_(names)
6.13 {
6.14 }
6.15
6.16 @@ -1103,17 +1104,25 @@
6.17 Handle<Importable> source() {
6.18 return source_;
6.19 }
6.20 - unsigned importIndex() {
6.21 + unsigned importIndex() const {
6.22 return importIndex_;
6.23 }
6.24 void setImportIndex(unsigned index) {
6.25 importIndex_ = index;
6.26 }
6.27 + NameList *names() const {
6.28 + return names_;
6.29 + }
6.30 +
6.31 + bool importAllNames() const {
6.32 + return names_ && names_->empty();
6.33 + }
6.34
6.35 private:
6.36 PathComponent *path_;
6.37 ScopedRoot<Importable> source_;
6.38 unsigned importIndex_;
6.39 + NameList *names_;
6.40 };
6.41
6.42 typedef StructureStatement::FieldList FieldList;
7.1 --- a/src/compiler/CompileContext.cpp Sun Jan 06 13:56:56 2013 -0800
7.2 +++ b/src/compiler/CompileContext.cpp Sat Jan 12 16:13:46 2013 -0800
7.3 @@ -271,7 +271,7 @@
7.4 CompileContext::compile()
7.5 {
7.6 // Phase 1. Parse all modules we're importing. This process may load new
7.7 - // modules off disk, and add them to the parse queue.
7.8 + // modules off disk and add them to the parse queue.
7.9 while (!unparsed_.empty()) {
7.10 TranslationUnit *unit = unparsed_.popCopy();
7.11
7.12 @@ -289,6 +289,9 @@
7.13 if (unit->failed())
7.14 continue;
7.15
7.16 + // Mark the module as currently in translation.
7.17 + unit->module()->setTranslationUnit(unit);
7.18 +
7.19 PopulateNamesAndTypes(zone_, *this, unit);
7.20 }
7.21
7.22 @@ -298,15 +301,12 @@
7.23 if (unit->failed())
7.24 continue;
7.25
7.26 - BindNamesAndTypes(zone_, *this, unit);
7.27 - }
7.28 + BindGlobals(zone_, *this, unit);
7.29
7.30 - // Phase 4. Assign types to every public name in the module.
7.31 - for (size_t i = 0; i < units_.length(); i++) {
7.32 - TranslationUnit *unit = units_[i];
7.33 if (unit->failed())
7.34 continue;
7.35
7.36 + BindNamesAndTypes(zone_, *this, unit);
7.37 }
7.38
7.39 // Intermediate phase. Decide which modules we should not perform
7.40 @@ -328,6 +328,10 @@
7.41 // Phase 5. Run modules.
7.42 for (size_t i = 0; i < units_.length(); i++) {
7.43 TranslationUnit *unit = units_[i];
7.44 +
7.45 + // Mark the unit as no longer being translated.
7.46 + unit->module()->setTranslationUnit(NULL);
7.47 +
7.48 if (unit->failed())
7.49 break;
7.50
8.1 --- a/src/compiler/NameBinding.cpp Sun Jan 06 13:56:56 2013 -0800
8.2 +++ b/src/compiler/NameBinding.cpp Sat Jan 12 16:13:46 2013 -0800
8.3 @@ -217,6 +217,11 @@
8.4 TypeSymbol *sym = new (pool_) TypeSymbol(scope, name, type);
8.5 if (!registerName(scope, sym))
8.6 return;
8.7 +
8.8 + if (scope->kind() == Scope::GLOBAL) {
8.9 + if (!unit_->globalScope()->exported()->append(sym))
8.10 + return;
8.11 + }
8.12 }
8.13
8.14 int value = 0;
8.15 @@ -236,6 +241,10 @@
8.16 ConstantSymbol *sym = new (pool_) ConstantSymbol(scope, entry.name, entry.pos, type, box);
8.17 if (!registerName(scope, sym))
8.18 return;
8.19 + if (scope->kind() == Scope::GLOBAL) {
8.20 + if (!unit_->globalScope()->exported()->append(sym))
8.21 + return;
8.22 + }
8.23
8.24 value++;
8.25 }
8.26 @@ -262,6 +271,9 @@
8.27 {
8.28 // We're in the global scope, for sure.
8.29 assert(env_->scope()->kind() == Scope::GLOBAL);
8.30 +
8.31 + if (!unit_->globalScope()->exported()->append(sym))
8.32 + return;
8.33 }
8.34
8.35 node->setSymbol(sym);
8.36 @@ -504,7 +516,6 @@
8.37 {
8.38 }
8.39
8.40 -
8.41 protected:
8.42 Type *buildVariableType(VariableDeclaration *node) {
8.43 Local<Type> type(zone_, bindType(node->type(), node->quals()));
8.44 @@ -762,7 +773,8 @@
8.45 {
8.46 public:
8.47 GlobalBuilder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
8.48 - : NameBinderBase(zone, cc, unit)
8.49 + : NameBinderBase(zone, cc, unit),
8.50 + globalScope_(unit->globalScope())
8.51 {
8.52 }
8.53
8.54 @@ -796,9 +808,10 @@
8.55 }
8.56
8.57 void visitNameProxy(NameProxy *proxy) {
8.58 - // Don't report errors here, since we'll report them later.
8.59 Scope *scope = unit_->globalScope();
8.60 Symbol *sym = scope->lookup(proxy->name());
8.61 + if (!sym)
8.62 + cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
8.63 proxy->bind(sym);
8.64 }
8.65
8.66 @@ -850,8 +863,7 @@
8.67 }
8.68
8.69 void visitImportStatement(ImportStatement *node) {
8.70 - // Eventually we'll handle |from| style imports as well.
8.71 - {
8.72 + if (!node->names()) {
8.73 PathComponent *path = node->path();
8.74 while (path->next)
8.75 path = path->next;
8.76 @@ -868,12 +880,48 @@
8.77 ImportSymbol *sym = new (pool_) ImportSymbol(unit_->importScope(), path->name, node->pos(), type, node->importIndex());
8.78 if (!unit_->importScope()->addSymbol(sym))
8.79 return;
8.80 + } else if (node->importAllNames()) {
8.81 + Local<Importable> importable(zone_, unit_->module()->getImportAt(node->importIndex()));
8.82 + if (importable->isPackage()) {
8.83 + assert(false);
8.84 + } else {
8.85 + Local<Module> module(zone_, Module::cast(importable));
8.86 + if (!module->globals())
8.87 + importAllFromTranslationUnit(node, module, module->translationUnit());
8.88 + else
8.89 + assert(false);
8.90 + }
8.91 + }
8.92 + }
8.93 +
8.94 + private:
8.95 + void importAllFromTranslationUnit(ImportStatement *node, Handle<Module> module, TranslationUnit *other) {
8.96 + assert(!other->failed());
8.97 +
8.98 + for (size_t i = 0; i < other->globalScope()->exported()->length(); i++) {
8.99 + Symbol *import = other->globalScope()->exported()->at(i);
8.100 + assert(import->type());
8.101 +
8.102 + // Check for duplicate import names.
8.103 + if (unit_->importScope()->localLookup(import->name())) {
8.104 + cc_.reportError(node->pos(), Message_DuplicateImport, import->name()->chars());
8.105 + return;
8.106 + }
8.107 +
8.108 + ImplicitSymbol *sym = new (pool_) ImplicitSymbol(unit_->importScope(),
8.109 + import->name(),
8.110 + node->pos(),
8.111 + import->type(),
8.112 + node->importIndex());
8.113 + if (!unit_->importScope()->addSymbol(sym))
8.114 + return;
8.115 }
8.116 }
8.117
8.118 private:
8.119 StructureBufferBuilder builder_;
8.120 Vector<ScopedRoot<Descriptor> *> descriptors_;
8.121 + GlobalScope *globalScope_;
8.122 };
8.123
8.124 class NameBinder : public NameBinderBase
8.125 @@ -1093,21 +1141,22 @@
8.126 };
8.127
8.128 void
8.129 -ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
8.130 +ke::BindGlobals(Zone *zone, CompileContext &cc, TranslationUnit *unit)
8.131 {
8.132 AutoEnterCompileContext enter(cc, unit);
8.133
8.134 - // Because of the way globals work in Pawn, we need a precursor step to
8.135 - // actually enter global symbols into the global struct. They're already
8.136 - // in the global symbol table, so we know they won't clash. This process
8.137 - // also binds any remaining types on global variables.
8.138 GlobalBuilder builder(zone, cc, unit);
8.139 Local<Struct> globals(zone, builder.build());
8.140 if (!globals || unit->failed())
8.141 return;
8.142
8.143 unit->module()->setGlobals(globals);
8.144 +}
8.145
8.146 +void
8.147 +ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
8.148 +{
8.149 + AutoEnterCompileContext enter(cc, unit);
8.150 NameBinder binder(zone, cc, unit);
8.151 binder.bind();
8.152 }
9.1 --- a/src/compiler/NameBinding.h Sun Jan 06 13:56:56 2013 -0800
9.2 +++ b/src/compiler/NameBinding.h Sat Jan 12 16:13:46 2013 -0800
9.3 @@ -29,9 +29,17 @@
9.4 class CompileContext;
9.5 struct TranslationUnit;
9.6
9.7 -// Creates symbols and types for names that are global or can be derived from a global.
9.8 +// Creates symbols and types for names that are global or can be derived from
9.9 +// a global. This phase also populates global scopes with lists of exported
9.10 +// symbols.
9.11 void PopulateNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit);
9.12
9.13 +// Because of the way globals work in Pawn, we need a precursor step to
9.14 +// actually enter global symbols into the global struct. They're already in
9.15 +// the global symbol table, so we know they won't clash. This process also
9.16 +// binds any remaining types on global variables.
9.17 +void BindGlobals(Zone *zone, CompileContext &cc, TranslationUnit *unit);
9.18 +
9.19 // Bind all outstanding names and finalize all unfinished types.
9.20 void BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit);
9.21
10.1 --- a/src/compiler/Parser.cpp Sun Jan 06 13:56:56 2013 -0800
10.2 +++ b/src/compiler/Parser.cpp Sat Jan 12 16:13:46 2013 -0800
10.3 @@ -1240,13 +1240,19 @@
10.4 }
10.5
10.6 ImportStatement *
10.7 -Parser::import()
10.8 +Parser::import(TokenKind kind)
10.9 {
10.10 SourcePosition pos = scanner_.begin();
10.11
10.12 - // import ::= import_path
10.13 - // import_path ::= name |
10.14 - // name "." import_path
10.15 + // import ::= "from" import_path "import" import_names
10.16 + // | "import" import_path
10.17 + // | "import" import_path ".*"
10.18 + // import_path ::= name
10.19 + // | name "." import_path
10.20 + // import_names ::= "*"
10.21 + // | import_name_list
10.22 + // import_name_list ::= name
10.23 + // | name "," import_name_list
10.24
10.25 Local<String> name(zone_, expectName());
10.26 if (!name)
10.27 @@ -1255,7 +1261,16 @@
10.28 PathComponent *root = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
10.29 PathComponent *current = root;
10.30
10.31 + // NULL namelist means that we do not import any names. An empty namelist
10.32 + // means we import all names.
10.33 + NameList *names = NULL;
10.34 +
10.35 while (match(TOK_DOT)) {
10.36 + if (kind == TOK_IMPORT && match(TOK_STAR)) {
10.37 + names = new (pool_) NameList();
10.38 + break;
10.39 + }
10.40 +
10.41 if ((name = expectName()) == NULL)
10.42 return NULL;
10.43
10.44 @@ -1263,7 +1278,31 @@
10.45 current = current->next;
10.46 }
10.47
10.48 - return new (pool_) ImportStatement(pos, root);
10.49 + if (kind == TOK_FROM) {
10.50 + if (!expect(TOK_IMPORT))
10.51 + return NULL;
10.52 +
10.53 + names = new (pool_) NameList();
10.54 +
10.55 + if (!match(TOK_STAR)) {
10.56 + if (!matchName(name.address())) {
10.57 + cc_.reportError(scanner_.begin(), Message_BadImportFrom);
10.58 + return NULL;
10.59 + }
10.60 +
10.61 + if (!name || !names->append(NewScopedRoot<String>(pool_, name)))
10.62 + return NULL;
10.63 +
10.64 + while (match(TOK_COMMA)) {
10.65 + if ((name = expectName()) == NULL)
10.66 + return NULL;
10.67 + if (!names->append(NewScopedRoot<String>(pool_, name)))
10.68 + return NULL;
10.69 + }
10.70 + }
10.71 + }
10.72 +
10.73 + return new (pool_) ImportStatement(pos, root, names);
10.74 }
10.75
10.76 Statement *
10.77 @@ -1391,12 +1430,13 @@
10.78 return NULL;
10.79 break;
10.80
10.81 + case TOK_FROM:
10.82 case TOK_IMPORT:
10.83 {
10.84 scanner_.scan();
10.85 if (statements->length())
10.86 cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst);
10.87 - ImportStatement *stmt = import();
10.88 + ImportStatement *stmt = import(kind);
10.89 if (!stmt)
10.90 return NULL;
10.91 if (!imports_->append(stmt))
11.1 --- a/src/compiler/Parser.h Sun Jan 06 13:56:56 2013 -0800
11.2 +++ b/src/compiler/Parser.h Sat Jan 12 16:13:46 2013 -0800
11.3 @@ -93,7 +93,7 @@
11.4 Statement *localStatement();
11.5 Statement *globalStatement();
11.6 Statement *returnStatement();
11.7 - ImportStatement *import();
11.8 + ImportStatement *import(TokenKind kind);
11.9
11.10 public:
11.11 Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length);
12.1 --- a/src/compiler/Scanner.cpp Sun Jan 06 13:56:56 2013 -0800
12.2 +++ b/src/compiler/Scanner.cpp Sat Jan 12 16:13:46 2013 -0800
12.3 @@ -438,6 +438,8 @@
12.4 return TOK_SIZEOF;
12.5 if (!strcmp(str, "import"))
12.6 return TOK_IMPORT;
12.7 + if (!strcmp(str, "from"))
12.8 + return TOK_FROM;
12.9 return TOK_NONE;
12.10 }
12.11
13.1 --- a/src/compiler/Scopes.h Sun Jan 06 13:56:56 2013 -0800
13.2 +++ b/src/compiler/Scopes.h Sat Jan 12 16:13:46 2013 -0800
13.3 @@ -101,8 +101,13 @@
13.4 public:
13.5 static GlobalScope *New(PoolAllocator &pool, ImportScope *parent);
13.6
13.7 + PoolList<Symbol *> *exported() {
13.8 + return &exported_;
13.9 + }
13.10 +
13.11 private:
13.12 GlobalScope(PoolAllocator &pool, ImportScope *parent);
13.13 + PoolList<Symbol *> exported_;
13.14 };
13.15
13.16 class ImportScope : public Scope
14.1 --- a/src/compiler/SemanticAnalysis.cpp Sun Jan 06 13:56:56 2013 -0800
14.2 +++ b/src/compiler/SemanticAnalysis.cpp Sat Jan 12 16:13:46 2013 -0800
14.3 @@ -559,6 +559,23 @@
14.4 return true;
14.5 }
14.6
14.7 +static unsigned
14.8 +BindImplicitName(Module *from, ImplicitSymbol *sym)
14.9 +{
14.10 + if (sym->bound())
14.11 + return sym->fieldIndex();
14.12 +
14.13 + Module *module = Module::cast(from->getImportAt(sym->index()));
14.14 + StructMap *map = module->globals()->map();
14.15 +
14.16 + unsigned fieldIndex;
14.17 + Descriptor *desc = map->type()->lookupField(sym->name(), &fieldIndex);
14.18 + assert(desc && desc->type() == sym->type());
14.19 +
14.20 + sym->bind(fieldIndex);
14.21 + return fieldIndex;
14.22 +}
14.23 +
14.24 void
14.25 SemanticAnalysis::visitNameProxy(NameProxy *proxy)
14.26 {
14.27 @@ -572,6 +589,16 @@
14.28 break;
14.29 }
14.30
14.31 + case Symbol::kImplicit:
14.32 + {
14.33 + ImplicitSymbol *import = sym->toImplicit();
14.34 + unsigned fieldIndex = BindImplicitName(unit_->module(), import);
14.35 +
14.36 + hir_ = new (pool_) HImport(proxy, zone_->types()->getImportable(), import->index());
14.37 + hir_ = new (pool_) HField(proxy, hir_, sym->type(), fieldIndex);
14.38 + break;
14.39 + }
14.40 +
14.41 case Symbol::kConstant:
14.42 {
14.43 ConstantSymbol *val = sym->toConstant();
15.1 --- a/src/compiler/Symbols.h Sun Jan 06 13:56:56 2013 -0800
15.2 +++ b/src/compiler/Symbols.h Sat Jan 12 16:13:46 2013 -0800
15.3 @@ -39,7 +39,9 @@
15.4 /* A named type (class struct, typedef, etc) produces a TypeSymbol. */ \
15.5 _(Type) \
15.6 /* An import name. */ \
15.7 - _(Import)
15.8 + _(Import) \
15.9 + /* A name implicitly derived from an import. */ \
15.10 + _(Implicit)
15.11
15.12 #define _(name) class name##Symbol;
15.13 SYMBOL_KINDS(_)
15.14 @@ -230,6 +232,40 @@
15.15 unsigned index_;
15.16 };
15.17
15.18 +class ImplicitSymbol : public Symbol
15.19 +{
15.20 + public:
15.21 + ImplicitSymbol(Scope *scope, Handle<String> name, const SourcePosition &pos, Handle<Type> type,
15.22 + unsigned index)
15.23 + : Symbol(scope, name, pos),
15.24 + index_(index),
15.25 + fieldIndex_(unsigned(-1))
15.26 + {
15.27 + type_ = type;
15.28 + }
15.29 +
15.30 + bool bound() const {
15.31 + return fieldIndex_ != unsigned(-1);
15.32 + }
15.33 + Kind kind() const {
15.34 + return kImplicit;
15.35 + }
15.36 + unsigned index() const {
15.37 + return index_;
15.38 + }
15.39 + void bind(unsigned fieldIndex) {
15.40 + fieldIndex_ = fieldIndex;
15.41 + }
15.42 + unsigned fieldIndex() const {
15.43 + assert(bound());
15.44 + return fieldIndex_;
15.45 + }
15.46 +
15.47 + private:
15.48 + unsigned index_;
15.49 + unsigned fieldIndex_;
15.50 +};
15.51 +
15.52 }
15.53
15.54 #endif // _include_sp2_symbol_h_
16.1 --- a/src/compiler/Token.h Sun Jan 06 13:56:56 2013 -0800
16.2 +++ b/src/compiler/Token.h Sat Jan 12 16:13:46 2013 -0800
16.3 @@ -61,6 +61,7 @@
16.4 _(INT, "<int>") \
16.5 _(SIZEOF, "<sizeof>") \
16.6 _(IMPORT, "<import>") \
16.7 + _(FROM, "<from>") \
16.8 _(ELLIPSES, "...") \
16.9 _(PLUS, "+") \
16.10 _(MINUS, "-") \
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/tests/basic/import-sysroot-all.out Sat Jan 12 16:13:46 2013 -0800
17.3 @@ -0,0 +1,1 @@
17.4 +5 is 5.000000
18.1 --- a/tests/basic/import-sysroot-all.sp Sun Jan 06 13:56:56 2013 -0800
18.2 +++ b/tests/basic/import-sysroot-all.sp Sat Jan 12 16:13:46 2013 -0800
18.3 @@ -1,4 +1,4 @@
18.4 -import shell.*;
18.5 +from shell import *;
18.6
18.7 public main()
18.8 {
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/tests/basic/import-sysroot-module.out Sat Jan 12 16:13:46 2013 -0800
19.3 @@ -0,0 +1,1 @@
19.4 +5 is 5.000000
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/tests/basic/import-sysroot-module.sp Sat Jan 12 16:13:46 2013 -0800
20.3 @@ -0,0 +1,9 @@
20.4 +import shell;
20.5 +
20.6 +public main()
20.7 +{
20.8 + shell.PrintNum(5);
20.9 + shell.PrintString(" is ");
20.10 + shell.PrintFloat(5.0);
20.11 +}
20.12 +
21.1 --- a/tests/basic/import-sysroot-select.out Sun Jan 06 13:56:56 2013 -0800
21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
21.3 @@ -1,1 +0,0 @@
21.4 -5 is 5.000000
22.1 --- a/tests/basic/import-sysroot-select.sp Sun Jan 06 13:56:56 2013 -0800
22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
22.3 @@ -1,9 +0,0 @@
22.4 -import shell;
22.5 -
22.6 -public main()
22.7 -{
22.8 - shell.PrintNum(5);
22.9 - shell.PrintString(" is ");
22.10 - shell.PrintFloat(5.0);
22.11 -}
22.12 -