jitcraft/SemanticAnalysis.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jul 03 00:54:40 2012 -0700 (2012-07-03)
changeset 37 abb03d835b53
parent 30 8c8bf75114f7
child 40 ce787d61fb71
permissions -rw-r--r--
Handleize NameBinding.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of JITCraft.
     6  *
     7  * JITCraft is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * JITCraft. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include "SemanticAnalysis.h"
    20 #include "Types.h"
    21 #include "Zone.h"
    22 #include "TypeManager.h"
    23 #include "Scopes.h"
    24 #include "Heap-inl.h"
    25 
    26 using namespace jc;
    27 
    28 static inline bool
    29 IsPrimitiveType(Type *type, PrimitiveType primitive)
    30 {
    31     if (!type)
    32         return false;
    33 
    34     if (!type->isPrimitive())
    35         return false;
    36 
    37     return primitive == type->primitive();
    38 }
    39 
    40 static inline bool
    41 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
    42                         BoxedPrimitive *out)
    43 {
    44     switch (kind) {
    45       case TOK_PLUS:
    46         *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
    47         return true;
    48 
    49       case TOK_SHL:
    50         *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
    51         return true;
    52 
    53       default:
    54 	return false;
    55     }
    56 }
    57 
    58 static bool
    59 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
    60 {
    61     switch (expression->kind()) {
    62       case AstNode::kBinaryExpression:
    63       {
    64         BoxedPrimitive left;
    65         BoxedPrimitive right;
    66         BinaryExpression *b = expression->toBinaryExpression();
    67         if (!EvaluateForConstant(b->left(), &left) ||
    68             !EvaluateForConstant(b->right(), &right))
    69         {
    70             return false;
    71         }
    72         return EvaluateBinaryOperation(b->token(), left, right, out);
    73       }
    74 
    75       case AstNode::kNameProxy:
    76       {
    77         NameProxy *proxy = expression->toNameProxy();
    78         if (proxy->binding()->kind() != BoundName::CONSTANT)
    79             return false;
    80 
    81         NamedConstant *c = proxy->binding()->toNamedConstant();
    82         if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
    83             return false;
    84 
    85         *out = c->value();
    86         return true;
    87       }
    88 
    89       case AstNode::kIntegerLiteral:
    90         *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
    91         return true;
    92 
    93       default:
    94         return false;
    95     }
    96 }
    97 
    98 SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
    99   : zone_(zone),
   100     cc_(cc),
   101     tree_(tree),
   102     loopDepth_(0),
   103     scope_(NULL)
   104 {
   105 }
   106 
   107 bool
   108 SemanticAnalysis::analyze()
   109 {
   110     if (cc_.failures())
   111         return false;
   112 
   113     for (size_t i = 0; i < tree_->statements()->length(); i++) {
   114         Statement *statement = tree_->statements()->at(i);
   115         if (statement->isFunctionStatement()) {
   116             FunctionStatement *funstmt = statement->toFunctionStatement();
   117             if (!preanalyze(funstmt))
   118                 return false;
   119         }
   120     }
   121 
   122     for (size_t i = 0; i < tree_->statements()->length(); i++) {
   123         Statement *statement = tree_->statements()->at(i);
   124         statement->accept(this);
   125     }
   126 
   127     return !cc_.failures();
   128 }
   129 
   130 Type *
   131 SemanticAnalysis::visitAndApplyType(Expression *expression)
   132 {
   133     expression->accept(this);
   134     return expression->type();
   135 }
   136 
   137 Type *
   138 SemanticAnalysis::visitForLoad(Expression *expression)
   139 {
   140     // :TODO: use Local
   141     Type *type = visitAndApplyType(expression);
   142     if (!type)
   143         return NULL;
   144 
   145     if (type->isReference()) {
   146         expression->setType(type->contained());
   147     } else if (expression->isIndexExpression()) {
   148         if (type->isArray())
   149             expression->setType(type->contained());
   150     }
   151 
   152     return expression->type();
   153 }
   154 
   155 Type *
   156 SemanticAnalysis::visitForRef(Expression *expression)
   157 {
   158     expression->accept(this);
   159     return expression->type();
   160 }
   161 
   162 static inline const char *
   163 GetTypeName(Type *type)
   164 {
   165     if (type->isArray())
   166         return "array";
   167     if (type->isFunction())
   168         return "function";
   169     if (type->isReference())
   170         type = type->contained();
   171     if (type->tag())
   172         return type->tag();
   173     return "int";
   174 }
   175 
   176 void
   177 SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Type *type)
   178 {
   179     const char *op = TokenNames[token];
   180     const char *name = GetTypeName(type);
   181 
   182     cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
   183 }
   184 
   185 void
   186 SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Type *left, Type *right)
   187 {
   188     const char *op = TokenNames[token];
   189     const char *leftName = GetTypeName(left);
   190     const char *rightName = GetTypeName(right);
   191 
   192     cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
   193 }
   194 
   195 Type *
   196 SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Type *left, Type *right)
   197 {
   198     if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
   199         (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
   200     {
   201         // If either side is a float, the other side must be a float or int.
   202         if (left->isFloat() || right->isFloat()) {
   203             Type *floatType = left->isFloat() ? left : right;
   204             Type *other = left->isFloat() ? right : left;
   205             if (other->isFloat() || (other->isInt32() && !other->tag()))
   206                 return floatType;
   207         }
   208     }
   209 
   210     if ((!left->isInt32() || left->tag()) ||
   211         (!right->isInt32() || right->tag()))
   212     {
   213         binaryTypeError(node, token, left, right);
   214         return NULL;
   215     }
   216 
   217     return left;
   218 }
   219 
   220 bool
   221 SemanticAnalysis::canTest(AstNode *node, Type *type)
   222 {
   223     if (type->isArray()) {
   224         cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
   225         return false;
   226     }
   227     return true;
   228 }
   229 
   230 Type *
   231 SemanticAnalysis::visitForLValue(Expression *expression)
   232 {
   233     if (expression->isIndexExpression()) {
   234         Type *type = visitAndApplyType(expression);
   235         if (!type)
   236             return NULL;
   237 
   238         return type->contained();
   239     }
   240 
   241     if (!expression->isNameProxy()) {
   242         cc_.reportError(expression->pos(), Message_ExpectedLValue);
   243         return NULL;
   244     }
   245 
   246     NameProxy *proxy = expression->toNameProxy();
   247     if (!proxy->binding()->kind() == BoundName::VARIABLE) {
   248         cc_.reportError(expression->pos(), Message_ExpectedLValue);
   249         return NULL;
   250     }
   251 
   252     Variable *var = proxy->binding()->toVariable();
   253     if (!var->type())
   254         return NULL;
   255 
   256     if  (var->type()->isReference())
   257         return var->type()->contained();
   258     return var->type();
   259 }
   260 
   261 void
   262 SemanticAnalysis::visit(NameProxy *name)
   263 {
   264     name->setType(name->binding()->type());
   265 }
   266 
   267 void
   268 SemanticAnalysis::visit(Assignment *node)
   269 {
   270     Type *exprType = visitForLoad(node->expression());
   271     if (!exprType)
   272         return ;
   273 
   274     // :TODO: use Local
   275     Type *type = visitForLValue(node->lvalue());
   276     if (!type)
   277         return;
   278 
   279     if (node->token() != TOK_ASSIGN) {
   280         if (!typeCheckBinary(node, node->token(), type, exprType))
   281             return;
   282     }
   283 
   284     if (!typeCheckAssignment(node, exprType, type, true))
   285         return;
   286 
   287     node->setType(type);
   288 }
   289 
   290 void
   291 SemanticAnalysis::visit(IncDecExpression *node)
   292 {
   293     // :TODO: use Local
   294     Type *type = visitForLValue(node->expression());
   295     if (!type)
   296         return;
   297 
   298     assert(!type->isReference());
   299 
   300     if ((!type->isInt32() || (type->isInt32() && type->tag())) && !type->isFloat()) {
   301         unaryTypeError(node, node->token(), type);
   302         return;
   303     }
   304 
   305     node->setType(type);
   306 }
   307 
   308 void
   309 SemanticAnalysis::visit(BinaryExpression *node)
   310 {
   311     // :TODO: use Local
   312     Type *left = visitForLoad(node->left());
   313     Type *right = visitForLoad(node->right());
   314     if (!left || !right)
   315         return;
   316 
   317     Type *result = typeCheckBinary(node, node->token(), left, right);
   318     if (!result)
   319         return;
   320 
   321     node->setType(result);
   322 }
   323 
   324 void
   325 SemanticAnalysis::visit(ReturnStatement *node)
   326 {
   327     Type *type = visitForLoad(node->expression());
   328     if (!type)
   329         return;
   330 
   331     if (!typeCheckAssignment(node, type, function_->returnType(), true))
   332         return;
   333 }
   334 
   335 void
   336 SemanticAnalysis::visit(ForStatement *node)
   337 {
   338     loopDepth_++;
   339     if (node->scope())
   340         scope_ = node->scope();
   341 
   342     if (node->initialization())
   343         node->initialization()->accept(this);
   344 
   345     if (node->condition()) {
   346         Type *type = visitForLoad(node->condition());
   347         if (!type || !canTest(node->condition(), type)) {
   348             loopDepth_--;
   349             return;
   350         }
   351     }
   352 
   353     if (node->update())
   354         node->update()->accept(this);
   355 
   356     node->body()->accept(this);
   357 
   358     if (node->scope())
   359         scope_ = scope_->enclosing();
   360     loopDepth_--;
   361 }
   362 
   363 void 
   364 SemanticAnalysis::visit(WhileStatement *node)
   365 {
   366     loopDepth_++;
   367 
   368     Type *type = visitForLoad(node->condition());
   369     if (!type || !canTest(node->condition(), type)) {
   370         loopDepth_--;
   371         return;
   372     }
   373 
   374     node->body()->accept(this);
   375     loopDepth_--;
   376 }
   377 
   378 void
   379 SemanticAnalysis::visit(BlockStatement *node)
   380 {
   381     if (node->scope())
   382         scope_ = node->scope();
   383     for (size_t i = 0; i < node->statements()->length(); i++) {
   384         Statement *statement = node->statements()->at(i);
   385         statement->accept(this);
   386     }
   387     if (node->scope())
   388         scope_ = scope_->enclosing();
   389 }
   390 
   391 void
   392 SemanticAnalysis::visit(VariableDeclaration *node)
   393 {
   394     Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(node->tag()));
   395     if (!type)
   396         return;
   397 
   398     if (node->postDimensions()) {
   399         Local<Type> init(zone_);
   400         if (node->initialization()) {
   401             if ((init = visitAndApplyType(node->initialization())) == NULL)
   402                 return;
   403         }
   404 
   405         if (node->postDimensions()->size() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
   406             cc_.reportError(node->pos(), Message_MaximumArrayDepth);
   407             return;
   408         }
   409 
   410         // If we have an initializer, make sure it's the same type.
   411         if (init && node->postDimensions()->size() != init->levels()) {
   412             cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
   413             return;
   414         }
   415 
   416         Local<Type> check(zone_, init);
   417         for (size_t i = node->postDimensions()->size() - 1; i < node->postDimensions()->size(); i--) {
   418             Expression *expr = node->postDimensions()->at(i);
   419             int size = -1;
   420 
   421             if (expr) {
   422                 Local<Type> exprType(zone_, visitForLoad(expr));
   423                 if (!exprType)
   424                     return;
   425 
   426                 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
   427                     cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   428                     return;
   429                 }
   430 
   431                 BoxedPrimitive box;
   432                 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
   433                     size = box.toInt();
   434                     if (size <= 0) {
   435                         cc_.reportError(expr->pos(), Message_BadArraySize);
   436                         return;
   437                     }
   438                     if (size >= INT_MAX / sizeof(int)) {
   439                         cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
   440                         return;
   441                     }
   442 
   443                     if (check) {
   444                         if (check->elements() == -1) {
   445                             cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
   446                             return;
   447                         }
   448 
   449                         if (check->isCharArray()) {
   450                             if (check->elements() > size) {
   451                                 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
   452                                 return;
   453                             }
   454                         } else if (check->elements() != size) {
   455                             cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
   456                             return;
   457                         }
   458                     }
   459                 } else {
   460                     if (init) {
   461                         cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
   462                         return;
   463                     }
   464 
   465                     // here until we get dynamic array support.
   466                     cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   467                     return;
   468                 }
   469             } else {
   470                 // Infer the size from the initializer.
   471                 if (!init) {
   472                     cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
   473                     return;
   474                 }
   475                 if (init->elements() == -1) {
   476                     cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
   477                     return;
   478                 }
   479                 size = init->elements();
   480             }
   481 
   482             type = zone_->types()->unsafeArray(type, size);
   483             if (!type)
   484                 return;
   485 
   486             if (check)
   487                 check = check->contained();
   488         }
   489 
   490         // Right now, any array is allowed on the LIFO heap. In case the
   491         // runtime actually decides to use the LIFO heap, we must reserve
   492         // a slot so we can unwind the heap when the current scope leaves.
   493         scope_->setUsesLifoHeap();
   494     } else {
   495         if (node->initialization()) {
   496             Type *right = visitForLoad(node->initialization());
   497             if (!right)
   498                 return;
   499             if (!typeCheckAssignment(node, type, right, true))
   500                 return;
   501         }
   502         if (type->primitive() == PrimitiveType_Char) {
   503             cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   504             return;
   505         }
   506     }
   507 
   508     node->variable()->setType(type);
   509 }
   510 
   511 void
   512 SemanticAnalysis::visit(IntegerLiteral *node)
   513 {
   514     node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
   515 }
   516 
   517 void
   518 SemanticAnalysis::visit(ExpressionStatement *node)
   519 {
   520     node->expression()->accept(this);
   521 }
   522 
   523 bool
   524 SemanticAnalysis::preanalyze(FunctionStatement *node)
   525 {
   526     Local<FixedArray> args(zone_, FixedArray::New(zone_, node->parameters()->size(), Heap::Tenure_Old));
   527     if (!args)
   528         return false;
   529 
   530     // Apply types to arguments.
   531     for (size_t i = 0; i < node->parameters()->size(); i++) {
   532         Parameter *parameter = node->parameters()->at(i);
   533         
   534         Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(parameter->tag()));
   535         if (!type)
   536             return false;
   537 
   538         if (type->primitive() == PrimitiveType_Char) {
   539             cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   540             return false;
   541         }
   542 
   543         if (parameter->reference()) {
   544             type = zone_->types()->getReference(type);
   545             if (!type)
   546                 return false;
   547         }
   548 
   549         args->set(zone_, i, type);
   550         parameter->variable()->setType(type);
   551     }
   552 
   553     Local<Type> returnType(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
   554     if (!returnType)
   555         return false;
   556 
   557     Local<Type> funtype(zone_, zone_->types()->newFunction(returnType, args));
   558     if (!funtype)
   559         return false;
   560 
   561     node->fun()->setType(funtype);
   562     return true;
   563 }
   564 
   565 void
   566 SemanticAnalysis::visit(FunctionStatement *node)
   567 {
   568     function_ = node->fun()->type();
   569     scope_ = node->scope();
   570     node->body()->accept(this);
   571     scope_ = NULL;
   572     function_ = NULL;
   573 }
   574 
   575 bool
   576 SemanticAnalysis::typeCheckArrayAssignment(AstNode *node, Type *given, Type *actual, bool forAssign)
   577 {
   578     if (!given->isArray()) {
   579         cc_.reportError(node->pos(), Message_ExpectedArray);
   580         return false;
   581     }
   582     if (given->levels() != actual->levels()) {
   583         cc_.reportError(node->pos(), Message_ArrayDimensionsMismatch);
   584         return false;
   585     }
   586 
   587     unsigned level = 0;
   588     while (given->isArray()) {
   589         if (actual->elements() != -1) {
   590             if (forAssign) {
   591                 if (given->elements() == -1 || actual->elements() == -1) {
   592                     cc_.reportError(node->pos(), Message_ArraySizeNotKnown);
   593                     return false;
   594                 }
   595 
   596                 if (actual->isCharArray()) {
   597                     // String assignment can have a truncated |given|.
   598                     if (given->elements() > actual->elements()) {
   599                         cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
   600                         return false;
   601                     }
   602                 } else {
   603                     if (given->elements() != actual->elements()) {
   604                         cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
   605                         return false;
   606                     }
   607                 }
   608             } else {
   609                 if (actual->elements() != -1 && given->elements() != actual->elements()) {
   610                     cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
   611                     return false;
   612                 }
   613             }
   614         }
   615         given = given->contained();
   616         actual = actual->contained();
   617     }
   618 
   619     if (given->primitive() != actual->primitive()) {
   620         const char *givenTag = given->tag() ? given->tag() : "_";
   621         const char *actualTag = given->tag() ? given->tag() : "_";
   622         cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
   623         return false;
   624     }
   625 
   626     return true;
   627 }
   628 
   629 bool
   630 SemanticAnalysis::typeCheckAssignment(AstNode *node, Type *given, Type *actual, bool forAssign)
   631 {
   632     if (actual->isArray())
   633         return typeCheckArrayAssignment(node, given, actual, forAssign);
   634 
   635     if (given->isArray()) {
   636         cc_.reportError(node->pos(), Message_CannotAssignArrayToScalar);
   637         return false;
   638     }
   639 
   640     if (!given->isPrimitive() || !actual->primitive()) {
   641         cc_.reportError(node->pos(), Message_UnsupportedType);
   642         return false;
   643     }
   644     
   645     // The given type may not have been dereferenced.
   646     if (given->isReference())
   647         given = given->contained();
   648     if (actual->isReference())
   649         actual = given->contained();
   650 
   651     if (given->primitive() != actual->primitive()) {
   652         const char *givenTag = given->tag() ? given->tag() : "_";
   653         const char *actualTag = given->tag() ? given->tag() : "_";
   654         cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
   655         return false;
   656     }
   657 
   658     return true;
   659 }
   660 
   661 bool
   662 SemanticAnalysis::typeCheckParameter(AstNode *node, Type *given, Type *actual)
   663 {
   664     return typeCheckAssignment(node, given, actual, false);
   665 }
   666 
   667 void
   668 SemanticAnalysis::visit(CallExpression *node)
   669 {
   670     Type *type = visitForLoad(node->callee());
   671     if (!type)
   672         return;
   673 
   674     if (!type->isFunction()) {
   675         cc_.reportError(node->pos(), Message_CalleeNotFunction);
   676         return;
   677     }
   678     if (node->arguments()->size() != type->parameters()->length()) {
   679         cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
   680         return;
   681     }
   682 
   683     for (unsigned i = 0; i < node->arguments()->size(); i++) {
   684         // Note: we don't compute references unless the callee needs a
   685         // reference type.
   686         Expression *expression = node->arguments()->at(i);
   687         Type *given = visitAndApplyType(expression);
   688         if (!given)
   689             return;
   690 
   691         // If it's an IndexExpression, we special case the ability to compute
   692         // a reference.
   693         if (expression->isIndexExpression())
   694             given = given->contained();
   695 
   696         Type *actual = type->parameterAt(i);
   697         if (!typeCheckParameter(expression, given, actual))
   698             return;
   699 
   700         // If the actual is a reference, and the given is not, we'll need to
   701         // compute a reference, which may be allocated on the stack.
   702         if (actual->isReference() && !given->isReference())
   703             scope_->setUsesLifoHeap();
   704     }
   705 }
   706 
   707 void
   708 SemanticAnalysis::visit(IfStatement *node)
   709 {
   710     Type *type = visitForLoad(node->condition());
   711     if (!type)
   712         return;
   713 
   714     if (!canTest(node, type))
   715         return;
   716 
   717     node->ifTrue()->accept(this);
   718     if (node->ifFalse())
   719         node->ifFalse()->accept(this);
   720 }
   721 
   722 void
   723 SemanticAnalysis::visit(IndexExpression *node)
   724 {
   725     // :TODO: use locals
   726     Type *left = visitForRef(node->left());
   727     Type *right = visitForLoad(node->right());
   728 
   729     if (!left || !right)
   730         return;
   731 
   732     if (!right->isInt32()) {
   733         cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
   734         return;
   735     }
   736     if (!left->isArray()) {
   737         cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
   738         return;
   739     }
   740     node->setType(left);
   741 }
   742 
   743 void
   744 SemanticAnalysis::visit(EnumStatement *node)
   745 {
   746     // Forbid the blessed types.
   747     Name *tag = node->name();
   748     if (!strcmp(tag, "Float") ||
   749         !strcmp(tag, "String") ||
   750         !strcmp(tag, "any") ||
   751         !strcmp(tag, "bool"))
   752     {
   753         cc_.reportError(node->pos(), Message_InvalidEnumName);
   754         return;
   755     }
   756 
   757     Type *type = zone_->types()->getPrimitiveForTag(tag);
   758     if (!type)
   759         return;
   760 
   761     int value = 0;
   762     for (size_t i = 0; i < node->entries()->size(); i++) {
   763         EnumStatement::Entry &entry = node->entries()->at(i);
   764 
   765         BoxedPrimitive box = BoxedPrimitive::Int(value);
   766         if (entry.expr) {
   767             entry.expr->accept(this);
   768             if (!EvaluateForConstant(entry.expr, &box)) {
   769                 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
   770                 return;
   771             }
   772 
   773             assert(box.type() == PrimitiveType_Int32);
   774             value = box.toInt();
   775         }
   776 
   777         entry.name->set(type, box);
   778         value++;
   779     }
   780 }
   781 
   782 void
   783 SemanticAnalysis::visit(StringLiteral *node)
   784 {
   785     Type *type = zone_->types()->getPrimitive(PrimitiveType_Char);
   786     if (!type)
   787         return;
   788 
   789     type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
   790     if (!type)
   791         return;
   792 
   793     node->setType(type);
   794 }
   795 
   796 void
   797 SemanticAnalysis::visit(FloatLiteral *node)
   798 {
   799     Type *type = zone_->types()->getPrimitive(PrimitiveType_Float);
   800     if (!type)
   801         return;
   802 
   803     node->setType(type);
   804 }
   805 
   806 void
   807 SemanticAnalysis::visit(BreakStatement *node)
   808 {
   809     if (loopDepth_ == 0)
   810         cc_.reportError(node->pos(), Message_BreakOutsideLoop);
   811 }
   812 
   813 void
   814 SemanticAnalysis::visit(ContinueStatement *node)
   815 {
   816     if (loopDepth_ == 0)
   817         cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
   818 }