# HG changeset patch # User Aziz K?ksal # Date 1205010140 -3600 # Node ID 9e6c6bb73e5f6bbac7ac825c37b8e3c398af7192 # Parent cb804053877249289e6bb7d902b57322a6ab9a89 Implemented visit methods for some type nodes. Added method SemanticPass2.search(). Added methods arrayOf() and arrayOf(Type) to class Type. Refactored ModuleScopeType. Added error msg UndefinedIdentifier. Added release.py. diff -r cb8040538772 -r 9e6c6bb73e5f trunk/README --- a/trunk/README Fri Mar 07 11:46:56 2008 +0100 +++ b/trunk/README Sat Mar 08 22:02:20 2008 +0100 @@ -11,8 +11,8 @@ How To Compile dil ================== In order to compile dil you need to have: - *) DMD 1.027 (http://www.digitalmars.com/d/1.0/changelog.html) - *) Tango 0.99.4 (http://dsource.org/projects/tango/) + *) DMD 1.028 (http://www.digitalmars.com/d/1.0/changelog.html) + *) Tango 0.99.5 (http://dsource.org/projects/tango/) *) DSSS 0.71 (http://dsource.org/projects/dsss/) If you can't compile dil because you have a newer version of these programs diff -r cb8040538772 -r 9e6c6bb73e5f trunk/release.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/release.py Sat Mar 08 22:02:20 2008 +0100 @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +# Author: Aziz Köksal + +# TODO: port release.sh to Python + +# TODO: write subcommand that creates a Makefile +def writeMakefile(): + pass diff -r cb8040538772 -r 9e6c6bb73e5f trunk/src/dil/Messages.d --- a/trunk/src/dil/Messages.d Fri Mar 07 11:46:56 2008 +0100 +++ b/trunk/src/dil/Messages.d Sat Mar 08 22:02:20 2008 +0100 @@ -154,6 +154,7 @@ auto ExpectedIdentOrInt = "expected an identifier or an integer, not '{}'"; auto MissingCatchOrFinally = "try statement is missing a catch or finally body."; // Semantic analysis: + auto UndefinedIdentifier = "undefined identifier '{}'"; auto DeclConflictsWithDecl = "declaration '{}' conflicts with declaration @{}"; auto VariableConflictsWithDecl = "variable '{}' conflicts with declaration @{}"; auto InterfaceCantHaveVariables = "an interface can't have member variables"; diff -r cb8040538772 -r 9e6c6bb73e5f trunk/src/dil/ast/DefaultVisitor.d --- a/trunk/src/dil/ast/DefaultVisitor.d Fri Mar 07 11:46:56 2008 +0100 +++ b/trunk/src/dil/ast/DefaultVisitor.d Sat Mar 08 22:02:20 2008 +0100 @@ -287,6 +287,7 @@ { //IllegalType, //IntegralType, + //ModuleScopeType, //IdentifierType have no subnodes. static if (is(T == QualifiedType)) visitT(t.lhs), visitT(t.rhs); @@ -308,8 +309,7 @@ visitT(t.returnType), visitN(t.params); static if (is(T == CFuncPointerType)) visitT(t.next), t.params && visitN(t.params); - static if (is(T == ModuleScopeType) || - is(T == BaseClassType) || + static if (is(T == BaseClassType) || is(T == ConstType) || is(T == InvariantType)) visitT(t.next); diff -r cb8040538772 -r 9e6c6bb73e5f trunk/src/dil/ast/NodeCopier.d --- a/trunk/src/dil/ast/NodeCopier.d Fri Mar 07 11:46:56 2008 +0100 +++ b/trunk/src/dil/ast/NodeCopier.d Sat Mar 08 22:02:20 2008 +0100 @@ -274,6 +274,7 @@ { //IllegalType, //IntegralType, + //ModuleScopeType, //IdentifierType have no subnodes. static if (is(T == QualifiedType)) mixin(doCopy(["lhs", "rhs"])); @@ -289,8 +290,7 @@ mixin(doCopy(["returnType", "params"])); static if (is(T == CFuncPointerType)) mixin(doCopy(["next", "params?"])); - static if (is(T == ModuleScopeType) || - is(T == BaseClassType) || + static if (is(T == BaseClassType) || is(T == ConstType) || is(T == InvariantType)) mixin(doCopy("next")); diff -r cb8040538772 -r 9e6c6bb73e5f trunk/src/dil/ast/Types.d --- a/trunk/src/dil/ast/Types.d Fri Mar 07 11:46:56 2008 +0100 +++ b/trunk/src/dil/ast/Types.d Sat Mar 08 22:02:20 2008 +0100 @@ -65,9 +65,8 @@ /// "." Type class ModuleScopeType : TypeNode { - this(TypeNode next) + this() { - super(next); mixin(set_kind); } mixin(copyMethod); diff -r cb8040538772 -r 9e6c6bb73e5f trunk/src/dil/parser/Parser.d --- a/trunk/src/dil/parser/Parser.d Fri Mar 07 11:46:56 2008 +0100 +++ b/trunk/src/dil/parser/Parser.d Sat Mar 08 22:02:20 2008 +0100 @@ -129,6 +129,13 @@ return node; } + /// Sets the begin and end tokens of a syntax tree node. + Class set(Class)(Class node, Token* begin, Token* end) + { + node.setTokens(begin, end); + return node; + } + /// Returns true if set() has been called on a node. static bool isNodeSet(Node node) { @@ -3431,8 +3438,8 @@ { auto begin = token; Type type; - if (consumed(T.Dot)) - type = set(new ModuleScopeType(parseIdentifierType()), begin); + if (token.kind == T.Dot) + type = set(new ModuleScopeType(), begin, begin); else if (token.kind == T.Typeof) type = parseTypeofType(); else diff -r cb8040538772 -r 9e6c6bb73e5f trunk/src/dil/semantic/Pass2.d --- a/trunk/src/dil/semantic/Pass2.d Fri Mar 07 11:46:56 2008 +0100 +++ b/trunk/src/dil/semantic/Pass2.d Sat Mar 08 22:02:20 2008 +0100 @@ -84,10 +84,40 @@ private alias Statement S; /// ditto private alias TypeNode T; /// ditto - /// The scope symbol to use in identifier or template instance expressions. - /// E.g.: object.method(); // After 'object' has been visited, dotIdScope is - /// // set, and 'method' will be looked up there. - //ScopeSymbol dotIdScope; + /// The current scope symbol to use for looking up identifiers. + /// E.g.: + /// --- + /// object.method(); // *) object is looked up in the current scope. + /// // *) idScope is set if object is a ScopeSymbol. + /// // *) method will be looked up in idScope. + /// dil.ast.Node.Node node; // A fully qualified type. + /// --- + ScopeSymbol idScope; + + /// Searches for a symbol. + Symbol search(Token* idTok) + { + assert(idTok.kind == TOK.Identifier); + auto id = idTok.ident; + Symbol symbol; + + if (idScope is null) + for (auto sc = scop; sc; sc = sc.parent) + { + symbol = sc.lookup(id); + if (symbol) + return symbol; + } + else + symbol = idScope.lookup(id); + + if (symbol is null) + error(idTok, MSG.UndefinedIdentifier, id.str); + else if (auto scopSymbol = cast(ScopeSymbol)symbol) + idScope = scopSymbol; + + return symbol; + } override { @@ -162,6 +192,8 @@ return md.decls; } + // Type nodes: + T visit(TypeofType t) { t.e = visitE(t.e); @@ -171,6 +203,15 @@ T visit(ArrayType t) { + auto baseType = visitT(t.next).type; + if (t.isAssociative) + t.type = baseType.arrayOf(visitT(t.assocType).type); + else if (t.isDynamic) + t.type = baseType.arrayOf(); + else if (t.isStatic) + {} + else + assert(t.isSlice); return t; } @@ -180,6 +221,38 @@ return t; } + T visit(QualifiedType t) + { + if (t.lhs.Is!(QualifiedType) is null) + idScope = null; // Reset at left-most type. + visitT(t.lhs); + visitT(t.rhs); + t.type = t.rhs.type; + return t; + } + + T visit(IdentifierType t) + { + auto idToken = t.begin; + auto symbol = search(idToken); + // TODO: save symbol or its type in t. + return t; + } + + T visit(TemplateInstanceType t) + { + auto idToken = t.begin; + auto symbol = search(idToken); + // TODO: save symbol or its type in t. + return t; + } + + T visit(ModuleScopeType t) + { + idScope = modul; + return t; + } + T visit(IntegralType t) { // A table mapping the kind of a token to its corresponding semantic Type. @@ -197,6 +270,8 @@ return t; } + // Expression nodes: + E visit(ParenExpression e) { if (!e.type) diff -r cb8040538772 -r 9e6c6bb73e5f trunk/src/dil/semantic/Types.d --- a/trunk/src/dil/semantic/Types.d Fri Mar 07 11:46:56 2008 +0100 +++ b/trunk/src/dil/semantic/Types.d Sat Mar 08 22:02:20 2008 +0100 @@ -36,6 +36,20 @@ return new TypePointer(this); } + /// Returns a dynamic array type using this type as its base. + TypeDArray arrayOf() + { + return new TypeDArray(this); + } + + /// Returns an associative array type using this type as its base. + /// Params: + /// key = the key type. + TypeAArray arrayOf(Type key) + { + return new TypeAArray(this, key); + } + /// Returns the byte size of this type. final size_t sizeOf() {