src/Parser.cpp
changeset 145 e9d804821c48
parent 143 393f1b8ac8c3
child 146 dc7d3b7a918c
     1.1 --- a/src/Parser.cpp	Mon Jul 30 22:30:38 2012 -0700
     1.2 +++ b/src/Parser.cpp	Wed Aug 01 22:32:59 2012 -0700
     1.3 @@ -22,6 +22,7 @@
     1.4  #include "FixedArray.h"
     1.5  #include "Heap.h"
     1.6  #include "Strings.h"
     1.7 +#include "TypeManager.h"
     1.8  #include "Heap-inl.h"
     1.9  
    1.10  using namespace ke;
    1.11 @@ -38,9 +39,15 @@
    1.12  }
    1.13  
    1.14  bool
    1.15 +Parser::peek(TokenKind kind)
    1.16 +{
    1.17 +    return scanner_.peek() == kind;
    1.18 +}
    1.19 +
    1.20 +bool
    1.21  Parser::match(TokenKind kind)
    1.22  {
    1.23 -    if (scanner_.peek() != kind)
    1.24 +    if (!peek(kind))
    1.25          return false;
    1.26      scanner_.scan();
    1.27      return true;
    1.28 @@ -81,6 +88,15 @@
    1.29      return proxy;
    1.30  }
    1.31  
    1.32 +BoundName *
    1.33 +Parser::bindType(Handle<String> name)
    1.34 +{
    1.35 +    if (BoundName *binding = scope_->lookup(name))
    1.36 +        return binding;
    1.37 +
    1.38 +    return new (pool_) UnboundName(scope_, name);
    1.39 +}
    1.40 +
    1.41  bool
    1.42  Parser::matchName(String **name, TokenKind kind)
    1.43  {
    1.44 @@ -284,11 +300,15 @@
    1.45          if (!tag)
    1.46              return NULL;
    1.47  
    1.48 +        BoundName *type = NULL;
    1.49 +        if (tag)
    1.50 +            type = bindType(tag);
    1.51 +
    1.52          Expression *expr = unary();
    1.53          if (!expr)
    1.54              return NULL;
    1.55  
    1.56 -        return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, tag);
    1.57 +        return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, type);
    1.58        }
    1.59  
    1.60        default:
    1.61 @@ -653,6 +673,25 @@
    1.62      return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
    1.63  }
    1.64  
    1.65 +ExpressionList *
    1.66 +Parser::dimensions()
    1.67 +{
    1.68 +    ExpressionList *postDimensions = new (pool_) ExpressionList();
    1.69 +    while (match(TOK_LBRACKET)) {
    1.70 +        Expression *dim = NULL;
    1.71 +        if (!match(TOK_RBRACKET)) {
    1.72 +            if ((dim = expression()) == NULL)
    1.73 +                return NULL;
    1.74 +            if (!expect(TOK_RBRACKET))
    1.75 +                return NULL;
    1.76 +        }
    1.77 +
    1.78 +        if (!postDimensions->append(dim))
    1.79 +            return NULL;
    1.80 +    }
    1.81 +    return postDimensions;
    1.82 +}
    1.83 +
    1.84  VariableDeclaration *
    1.85  Parser::variableDeclaration(TokenKind kind)
    1.86  {
    1.87 @@ -660,6 +699,10 @@
    1.88      if (matchName(tag.ref(), TOK_LABEL) && !tag)
    1.89          return NULL;
    1.90  
    1.91 +    BoundName *type = NULL;
    1.92 +    if (tag)
    1.93 +        type = bindType(tag);
    1.94 +
    1.95      Local<String> name(zone_, expectName());
    1.96      if (!name)
    1.97          return NULL;
    1.98 @@ -674,20 +717,9 @@
    1.99          return NULL;
   1.100  
   1.101      ExpressionList *postDimensions = NULL;
   1.102 -    if (scanner_.peek() == TOK_LBRACKET) {
   1.103 -        postDimensions = new (pool_) ExpressionList();
   1.104 -        while (match(TOK_LBRACKET)) {
   1.105 -            Expression *dim = NULL;
   1.106 -            if (!match(TOK_RBRACKET)) {
   1.107 -                if ((dim = expression()) == NULL)
   1.108 -                    return NULL;
   1.109 -                if (!expect(TOK_RBRACKET))
   1.110 -                    return NULL;
   1.111 -            }
   1.112 -
   1.113 -            if (!postDimensions->append(dim))
   1.114 -                return NULL;
   1.115 -        }
   1.116 +    if (peek(TOK_LBRACKET)) {
   1.117 +        if ((postDimensions = dimensions()) == NULL)
   1.118 +            return NULL;
   1.119      }
   1.120      
   1.121      Expression *expr = NULL;
   1.122 @@ -696,7 +728,7 @@
   1.123              return NULL;
   1.124      }
   1.125  
   1.126 -    return new (pool_) VariableDeclaration(var->pos(), kind, var, tag, postDimensions, expr);
   1.127 +    return new (pool_) VariableDeclaration(var->pos(), kind, var, type, postDimensions, expr);
   1.128  }
   1.129  
   1.130  Statement *
   1.131 @@ -886,6 +918,7 @@
   1.132  {
   1.133      expect(TOK_ENUM);
   1.134  
   1.135 +    NamedType *type = NULL;
   1.136      SourcePosition pos = scanner_.begin();
   1.137  
   1.138      Local<String> name(zone_);
   1.139 @@ -898,7 +931,7 @@
   1.140              return NULL;
   1.141          }
   1.142  
   1.143 -        if (!scope_->declareEnum(name, scanner_.begin()))
   1.144 +        if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
   1.145              return NULL;
   1.146      }
   1.147  
   1.148 @@ -936,15 +969,27 @@
   1.149      if (!expect(TOK_RBRACE))
   1.150          return NULL;
   1.151  
   1.152 -    return new (pool_) EnumStatement(pos, name, entries);
   1.153 +    return new (pool_) EnumStatement(pos, type, name, entries);
   1.154  }
   1.155  
   1.156  Statement *
   1.157  Parser::function(TokenKind token)
   1.158  {
   1.159      Local<String> returnTag(zone_);
   1.160 -    if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag)
   1.161 -        return NULL;
   1.162 +    if (token == TOK_LABEL) {
   1.163 +        returnTag = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
   1.164 +        if (!returnTag)
   1.165 +            return NULL;
   1.166 +
   1.167 +        token = TOK_STOCK;
   1.168 +    } else {
   1.169 +        if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag)
   1.170 +            return NULL;
   1.171 +    }
   1.172 +
   1.173 +    BoundName *returnType = NULL;
   1.174 +    if (returnTag)
   1.175 +        returnType = bindType(returnTag);
   1.176  
   1.177      Local<String> name(zone_, expectName());
   1.178      if (!name)
   1.179 @@ -1001,6 +1046,10 @@
   1.180              if (matchName(tag.ref(), TOK_LABEL) && !tag)
   1.181                  return NULL;
   1.182  
   1.183 +            BoundName *type = NULL;
   1.184 +            if (tag)
   1.185 +                type = bindType(tag);
   1.186 +
   1.187              if (match(TOK_ELLIPSES)) {
   1.188                  if (isConst || ref) {
   1.189                      cc_.reportError(begin, Message_InvalidVarArgs);
   1.190 @@ -1030,19 +1079,8 @@
   1.191  
   1.192              // Look for dimensions.
   1.193              ExpressionList *postDimensions = NULL;
   1.194 -            while (match(TOK_LBRACKET)) {
   1.195 -                if (!postDimensions)
   1.196 -                    postDimensions = new (pool_) ExpressionList();
   1.197 -
   1.198 -                Expression *dim = NULL;
   1.199 -                if (!match(TOK_RBRACKET)) {
   1.200 -                    if ((dim = expression()) == NULL)
   1.201 -                        return NULL;
   1.202 -                    if (!expect(TOK_RBRACKET))
   1.203 -                        return NULL;
   1.204 -                }
   1.205 -
   1.206 -                if (!postDimensions->append(dim))
   1.207 +            if (peek(TOK_LBRACKET)) {
   1.208 +                if ((postDimensions = dimensions()) == NULL)
   1.209                      return NULL;
   1.210              }
   1.211  
   1.212 @@ -1052,7 +1090,7 @@
   1.213                      return NULL;
   1.214              }
   1.215  
   1.216 -            Parameter *parameter = new (pool_) Parameter(arg, tag, ref, isConst, postDimensions,
   1.217 +            Parameter *parameter = new (pool_) Parameter(arg, type, ref, isConst, postDimensions,
   1.218                                                           expr);
   1.219              if (!parameters->append(parameter))
   1.220                  return NULL;
   1.221 @@ -1074,10 +1112,37 @@
   1.222      }
   1.223  
   1.224      scope_ = scope_->enclosing();
   1.225 -    return new (pool_) FunctionStatement(pos, scope, fun, body, parameters, returnTag,
   1.226 +    return new (pool_) FunctionStatement(pos, scope, fun, body, parameters, returnType,
   1.227                                           encounteredReturn_);
   1.228  }
   1.229  
   1.230 +static inline bool
   1.231 +DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type)
   1.232 +{
   1.233 +    Local<String> tag(zone, zone->makeSymbol(name));
   1.234 +    if (!tag)
   1.235 +        return false;
   1.236 +
   1.237 +    Local<Type> primitive(zone, zone->types()->getPrimitive(type));
   1.238 +    assert(primitive);
   1.239 +
   1.240 +    return !!scope->declareType(tag, primitive);
   1.241 +}
   1.242 +
   1.243 +bool
   1.244 +Parser::setupIntrinsics()
   1.245 +{
   1.246 +    if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float))
   1.247 +        return false;
   1.248 +    if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32))
   1.249 +        return false;
   1.250 +    if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool))
   1.251 +        return false;
   1.252 +    if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char))
   1.253 +        return false;
   1.254 +    return true;
   1.255 +}
   1.256 +
   1.257  ParseTree *
   1.258  Parser::parse()
   1.259  {
   1.260 @@ -1086,6 +1151,9 @@
   1.261      if (!enterScope(Scope::GLOBAL))
   1.262          return NULL;
   1.263  
   1.264 +    if (!setupIntrinsics())
   1.265 +        return NULL;
   1.266 +
   1.267      for (;;) {
   1.268          Statement *statement = NULL;
   1.269  
   1.270 @@ -1106,6 +1174,7 @@
   1.271            case TOK_PUBLIC:
   1.272            case TOK_NATIVE:
   1.273            case TOK_STOCK:
   1.274 +          case TOK_LABEL:
   1.275            {
   1.276              scanner_.scan();
   1.277              if ((statement = function(kind)) == NULL)