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)