diff -r a8735148dcf0 -r e9d804821c48 src/Parser.cpp --- a/src/Parser.cpp Mon Jul 30 22:30:38 2012 -0700 +++ b/src/Parser.cpp Wed Aug 01 22:32:59 2012 -0700 @@ -22,6 +22,7 @@ #include "FixedArray.h" #include "Heap.h" #include "Strings.h" +#include "TypeManager.h" #include "Heap-inl.h" using namespace ke; @@ -38,9 +39,15 @@ } bool +Parser::peek(TokenKind kind) +{ + return scanner_.peek() == kind; +} + +bool Parser::match(TokenKind kind) { - if (scanner_.peek() != kind) + if (!peek(kind)) return false; scanner_.scan(); return true; @@ -81,6 +88,15 @@ return proxy; } +BoundName * +Parser::bindType(Handle name) +{ + if (BoundName *binding = scope_->lookup(name)) + return binding; + + return new (pool_) UnboundName(scope_, name); +} + bool Parser::matchName(String **name, TokenKind kind) { @@ -284,11 +300,15 @@ if (!tag) return NULL; + BoundName *type = NULL; + if (tag) + type = bindType(tag); + Expression *expr = unary(); if (!expr) return NULL; - return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, tag); + return new (pool_) UnaryExpression(pos, TOK_LABEL, expr, type); } default: @@ -653,6 +673,25 @@ return new (pool_) ForStatement(pos, declScope, decl, condition, update, body); } +ExpressionList * +Parser::dimensions() +{ + ExpressionList *postDimensions = new (pool_) ExpressionList(); + while (match(TOK_LBRACKET)) { + Expression *dim = NULL; + if (!match(TOK_RBRACKET)) { + if ((dim = expression()) == NULL) + return NULL; + if (!expect(TOK_RBRACKET)) + return NULL; + } + + if (!postDimensions->append(dim)) + return NULL; + } + return postDimensions; +} + VariableDeclaration * Parser::variableDeclaration(TokenKind kind) { @@ -660,6 +699,10 @@ if (matchName(tag.ref(), TOK_LABEL) && !tag) return NULL; + BoundName *type = NULL; + if (tag) + type = bindType(tag); + Local name(zone_, expectName()); if (!name) return NULL; @@ -674,20 +717,9 @@ return NULL; ExpressionList *postDimensions = NULL; - if (scanner_.peek() == TOK_LBRACKET) { - postDimensions = new (pool_) ExpressionList(); - while (match(TOK_LBRACKET)) { - Expression *dim = NULL; - if (!match(TOK_RBRACKET)) { - if ((dim = expression()) == NULL) - return NULL; - if (!expect(TOK_RBRACKET)) - return NULL; - } - - if (!postDimensions->append(dim)) - return NULL; - } + if (peek(TOK_LBRACKET)) { + if ((postDimensions = dimensions()) == NULL) + return NULL; } Expression *expr = NULL; @@ -696,7 +728,7 @@ return NULL; } - return new (pool_) VariableDeclaration(var->pos(), kind, var, tag, postDimensions, expr); + return new (pool_) VariableDeclaration(var->pos(), kind, var, type, postDimensions, expr); } Statement * @@ -886,6 +918,7 @@ { expect(TOK_ENUM); + NamedType *type = NULL; SourcePosition pos = scanner_.begin(); Local name(zone_); @@ -898,7 +931,7 @@ return NULL; } - if (!scope_->declareEnum(name, scanner_.begin())) + if ((type = scope_->declareType(name, scanner_.begin())) == NULL) return NULL; } @@ -936,15 +969,27 @@ if (!expect(TOK_RBRACE)) return NULL; - return new (pool_) EnumStatement(pos, name, entries); + return new (pool_) EnumStatement(pos, type, name, entries); } Statement * Parser::function(TokenKind token) { Local returnTag(zone_); - if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag) - return NULL; + if (token == TOK_LABEL) { + returnTag = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length()); + if (!returnTag) + return NULL; + + token = TOK_STOCK; + } else { + if (matchName(returnTag.ref(), TOK_LABEL) && !returnTag) + return NULL; + } + + BoundName *returnType = NULL; + if (returnTag) + returnType = bindType(returnTag); Local name(zone_, expectName()); if (!name) @@ -1001,6 +1046,10 @@ if (matchName(tag.ref(), TOK_LABEL) && !tag) return NULL; + BoundName *type = NULL; + if (tag) + type = bindType(tag); + if (match(TOK_ELLIPSES)) { if (isConst || ref) { cc_.reportError(begin, Message_InvalidVarArgs); @@ -1030,19 +1079,8 @@ // Look for dimensions. ExpressionList *postDimensions = NULL; - while (match(TOK_LBRACKET)) { - if (!postDimensions) - postDimensions = new (pool_) ExpressionList(); - - Expression *dim = NULL; - if (!match(TOK_RBRACKET)) { - if ((dim = expression()) == NULL) - return NULL; - if (!expect(TOK_RBRACKET)) - return NULL; - } - - if (!postDimensions->append(dim)) + if (peek(TOK_LBRACKET)) { + if ((postDimensions = dimensions()) == NULL) return NULL; } @@ -1052,7 +1090,7 @@ return NULL; } - Parameter *parameter = new (pool_) Parameter(arg, tag, ref, isConst, postDimensions, + Parameter *parameter = new (pool_) Parameter(arg, type, ref, isConst, postDimensions, expr); if (!parameters->append(parameter)) return NULL; @@ -1074,10 +1112,37 @@ } scope_ = scope_->enclosing(); - return new (pool_) FunctionStatement(pos, scope, fun, body, parameters, returnTag, + return new (pool_) FunctionStatement(pos, scope, fun, body, parameters, returnType, encounteredReturn_); } +static inline bool +DeclareIntrinsicType(Zone *zone, Scope *scope, const char *name, PrimitiveType type) +{ + Local tag(zone, zone->makeSymbol(name)); + if (!tag) + return false; + + Local primitive(zone, zone->types()->getPrimitive(type)); + assert(primitive); + + return !!scope->declareType(tag, primitive); +} + +bool +Parser::setupIntrinsics() +{ + if (!DeclareIntrinsicType(zone_, scope_, "Float", PrimitiveType_Float)) + return false; + if (!DeclareIntrinsicType(zone_, scope_, "_", PrimitiveType_Int32)) + return false; + if (!DeclareIntrinsicType(zone_, scope_, "bool", PrimitiveType_Bool)) + return false; + if (!DeclareIntrinsicType(zone_, scope_, "String", PrimitiveType_Char)) + return false; + return true; +} + ParseTree * Parser::parse() { @@ -1086,6 +1151,9 @@ if (!enterScope(Scope::GLOBAL)) return NULL; + if (!setupIntrinsics()) + return NULL; + for (;;) { Statement *statement = NULL; @@ -1106,6 +1174,7 @@ case TOK_PUBLIC: case TOK_NATIVE: case TOK_STOCK: + case TOK_LABEL: { scanner_.scan(); if ((statement = function(kind)) == NULL)