jitcraft/SemanticAnalysis.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jul 03 00:25:29 2012 -0700 (2012-07-03)
changeset 30 8c8bf75114f7
parent 28 a9665857cfd5
child 37 abb03d835b53
permissions -rw-r--r--
Remove calls to ZONE().
     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     // :TODO: use locals
   395     Type *type = zone_->types()->getPrimitiveForTag(node->tag());
   396     if (!type)
   397         return;
   398 
   399     if (node->postDimensions()) {
   400         Type *init = NULL;
   401         if (node->initialization()) {
   402             if ((init = visitAndApplyType(node->initialization())) == NULL)
   403                 return;
   404         }
   405 
   406         if (node->postDimensions()->size() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
   407             cc_.reportError(node->pos(), Message_MaximumArrayDepth);
   408             return;
   409         }
   410 
   411         // If we have an initializer, make sure it's the same type.
   412         if (init && node->postDimensions()->size() != init->levels()) {
   413             cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
   414             return;
   415         }
   416 
   417         Type *check = init;
   418         for (size_t i = node->postDimensions()->size() - 1; i < node->postDimensions()->size(); i--) {
   419             Expression *expr = node->postDimensions()->at(i);
   420             int size = -1;
   421 
   422             if (expr) {
   423                 Type *exprType = visitForLoad(expr);
   424                 if (!exprType)
   425                     return;
   426 
   427                 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
   428                     cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   429                     return;
   430                 }
   431 
   432                 BoxedPrimitive box;
   433                 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
   434                     size = box.toInt();
   435                     if (size <= 0) {
   436                         cc_.reportError(expr->pos(), Message_BadArraySize);
   437                         return;
   438                     }
   439                     if (size >= INT_MAX / sizeof(int)) {
   440                         cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
   441                         return;
   442                     }
   443 
   444                     if (check) {
   445                         if (check->elements() == -1) {
   446                             cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
   447                             return;
   448                         }
   449 
   450                         if (check->isCharArray()) {
   451                             if (check->elements() > size) {
   452                                 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
   453                                 return;
   454                             }
   455                         } else if (check->elements() != size) {
   456                             cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
   457                             return;
   458                         }
   459                     }
   460                 } else {
   461                     if (init) {
   462                         cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
   463                         return;
   464                     }
   465 
   466                     // here until we get dynamic array support.
   467                     cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   468                     return;
   469                 }
   470             } else {
   471                 // Infer the size from the initializer.
   472                 if (!init) {
   473                     cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
   474                     return;
   475                 }
   476                 if (init->elements() == -1) {
   477                     cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
   478                     return;
   479                 }
   480                 size = init->elements();
   481             }
   482 
   483             type = zone_->types()->unsafeArray(type, size);
   484             if (!type)
   485                 return;
   486 
   487             if (check)
   488                 check = check->contained();
   489         }
   490 
   491         // Right now, any array is allowed on the LIFO heap. In case the
   492         // runtime actually decides to use the LIFO heap, we must reserve
   493         // a slot so we can unwind the heap when the current scope leaves.
   494         scope_->setUsesLifoHeap();
   495     } else {
   496         if (node->initialization()) {
   497             Type *right = visitForLoad(node->initialization());
   498             if (!right)
   499                 return;
   500             if (!typeCheckAssignment(node, type, right, true))
   501                 return;
   502         }
   503         if (type->primitive() == PrimitiveType_Char) {
   504             cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   505             return;
   506         }
   507     }
   508 
   509     node->variable()->setType(type);
   510 }
   511 
   512 void
   513 SemanticAnalysis::visit(IntegerLiteral *node)
   514 {
   515     node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
   516 }
   517 
   518 void
   519 SemanticAnalysis::visit(ExpressionStatement *node)
   520 {
   521     node->expression()->accept(this);
   522 }
   523 
   524 bool
   525 SemanticAnalysis::preanalyze(FunctionStatement *node)
   526 {
   527     // :TODO: use Local
   528 
   529     FixedArray *args = FixedArray::New(zone_, node->parameters()->size(), Heap::Tenure_Old);
   530     if (!args)
   531         return false;
   532 
   533     // Apply types to arguments.
   534     for (size_t i = 0; i < node->parameters()->size(); i++) {
   535         Parameter *parameter = node->parameters()->at(i);
   536         
   537         Type *type = zone_->types()->getPrimitiveForTag(parameter->tag());
   538         if (!type)
   539             return false;
   540 
   541         if (type->primitive() == PrimitiveType_Char) {
   542             cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   543             return false;
   544         }
   545 
   546         if (parameter->reference()) {
   547             type = zone_->types()->getReference(type);
   548             if (!type)
   549                 return false;
   550         }
   551 
   552         args->set(zone_, i, type);
   553         parameter->variable()->setType(type);
   554     }
   555 
   556     Type *returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
   557     if (!returnType)
   558         return false;
   559 
   560     Type *funtype = zone_->types()->newFunction(returnType, args);
   561     if (!funtype)
   562         return false;
   563 
   564     node->fun()->setType(funtype);
   565     return true;
   566 }
   567 
   568 void
   569 SemanticAnalysis::visit(FunctionStatement *node)
   570 {
   571     function_ = node->fun()->type();
   572     scope_ = node->scope();
   573     node->body()->accept(this);
   574     scope_ = NULL;
   575     function_ = NULL;
   576 }
   577 
   578 bool
   579 SemanticAnalysis::typeCheckArrayAssignment(AstNode *node, Type *given, Type *actual, bool forAssign)
   580 {
   581     if (!given->isArray()) {
   582         cc_.reportError(node->pos(), Message_ExpectedArray);
   583         return false;
   584     }
   585     if (given->levels() != actual->levels()) {
   586         cc_.reportError(node->pos(), Message_ArrayDimensionsMismatch);
   587         return false;
   588     }
   589 
   590     unsigned level = 0;
   591     while (given->isArray()) {
   592         if (actual->elements() != -1) {
   593             if (forAssign) {
   594                 if (given->elements() == -1 || actual->elements() == -1) {
   595                     cc_.reportError(node->pos(), Message_ArraySizeNotKnown);
   596                     return false;
   597                 }
   598 
   599                 if (actual->isCharArray()) {
   600                     // String assignment can have a truncated |given|.
   601                     if (given->elements() > actual->elements()) {
   602                         cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
   603                         return false;
   604                     }
   605                 } else {
   606                     if (given->elements() != actual->elements()) {
   607                         cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
   608                         return false;
   609                     }
   610                 }
   611             } else {
   612                 if (actual->elements() != -1 && given->elements() != actual->elements()) {
   613                     cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
   614                     return false;
   615                 }
   616             }
   617         }
   618         given = given->contained();
   619         actual = actual->contained();
   620     }
   621 
   622     if (given->primitive() != actual->primitive()) {
   623         const char *givenTag = given->tag() ? given->tag() : "_";
   624         const char *actualTag = given->tag() ? given->tag() : "_";
   625         cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
   626         return false;
   627     }
   628 
   629     return true;
   630 }
   631 
   632 bool
   633 SemanticAnalysis::typeCheckAssignment(AstNode *node, Type *given, Type *actual, bool forAssign)
   634 {
   635     if (actual->isArray())
   636         return typeCheckArrayAssignment(node, given, actual, forAssign);
   637 
   638     if (given->isArray()) {
   639         cc_.reportError(node->pos(), Message_CannotAssignArrayToScalar);
   640         return false;
   641     }
   642 
   643     if (!given->isPrimitive() || !actual->primitive()) {
   644         cc_.reportError(node->pos(), Message_UnsupportedType);
   645         return false;
   646     }
   647     
   648     // The given type may not have been dereferenced.
   649     if (given->isReference())
   650         given = given->contained();
   651     if (actual->isReference())
   652         actual = given->contained();
   653 
   654     if (given->primitive() != actual->primitive()) {
   655         const char *givenTag = given->tag() ? given->tag() : "_";
   656         const char *actualTag = given->tag() ? given->tag() : "_";
   657         cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
   658         return false;
   659     }
   660 
   661     return true;
   662 }
   663 
   664 bool
   665 SemanticAnalysis::typeCheckParameter(AstNode *node, Type *given, Type *actual)
   666 {
   667     return typeCheckAssignment(node, given, actual, false);
   668 }
   669 
   670 void
   671 SemanticAnalysis::visit(CallExpression *node)
   672 {
   673     Type *type = visitForLoad(node->callee());
   674     if (!type)
   675         return;
   676 
   677     if (!type->isFunction()) {
   678         cc_.reportError(node->pos(), Message_CalleeNotFunction);
   679         return;
   680     }
   681     if (node->arguments()->size() != type->parameters()->length()) {
   682         cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
   683         return;
   684     }
   685 
   686     for (unsigned i = 0; i < node->arguments()->size(); i++) {
   687         // Note: we don't compute references unless the callee needs a
   688         // reference type.
   689         Expression *expression = node->arguments()->at(i);
   690         Type *given = visitAndApplyType(expression);
   691         if (!given)
   692             return;
   693 
   694         // If it's an IndexExpression, we special case the ability to compute
   695         // a reference.
   696         if (expression->isIndexExpression())
   697             given = given->contained();
   698 
   699         Type *actual = type->parameterAt(i);
   700         if (!typeCheckParameter(expression, given, actual))
   701             return;
   702 
   703         // If the actual is a reference, and the given is not, we'll need to
   704         // compute a reference, which may be allocated on the stack.
   705         if (actual->isReference() && !given->isReference())
   706             scope_->setUsesLifoHeap();
   707     }
   708 }
   709 
   710 void
   711 SemanticAnalysis::visit(IfStatement *node)
   712 {
   713     Type *type = visitForLoad(node->condition());
   714     if (!type)
   715         return;
   716 
   717     if (!canTest(node, type))
   718         return;
   719 
   720     node->ifTrue()->accept(this);
   721     if (node->ifFalse())
   722         node->ifFalse()->accept(this);
   723 }
   724 
   725 void
   726 SemanticAnalysis::visit(IndexExpression *node)
   727 {
   728     // :TODO: use locals
   729     Type *left = visitForRef(node->left());
   730     Type *right = visitForLoad(node->right());
   731 
   732     if (!left || !right)
   733         return;
   734 
   735     if (!right->isInt32()) {
   736         cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
   737         return;
   738     }
   739     if (!left->isArray()) {
   740         cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
   741         return;
   742     }
   743     node->setType(left);
   744 }
   745 
   746 void
   747 SemanticAnalysis::visit(EnumStatement *node)
   748 {
   749     // Forbid the blessed types.
   750     Name *tag = node->name();
   751     if (!strcmp(tag, "Float") ||
   752         !strcmp(tag, "String") ||
   753         !strcmp(tag, "any") ||
   754         !strcmp(tag, "bool"))
   755     {
   756         cc_.reportError(node->pos(), Message_InvalidEnumName);
   757         return;
   758     }
   759 
   760     Type *type = zone_->types()->getPrimitiveForTag(tag);
   761     if (!type)
   762         return;
   763 
   764     int value = 0;
   765     for (size_t i = 0; i < node->entries()->size(); i++) {
   766         EnumStatement::Entry &entry = node->entries()->at(i);
   767 
   768         BoxedPrimitive box = BoxedPrimitive::Int(value);
   769         if (entry.expr) {
   770             entry.expr->accept(this);
   771             if (!EvaluateForConstant(entry.expr, &box)) {
   772                 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
   773                 return;
   774             }
   775 
   776             assert(box.type() == PrimitiveType_Int32);
   777             value = box.toInt();
   778         }
   779 
   780         entry.name->set(type, box);
   781         value++;
   782     }
   783 }
   784 
   785 void
   786 SemanticAnalysis::visit(StringLiteral *node)
   787 {
   788     Type *type = zone_->types()->getPrimitive(PrimitiveType_Char);
   789     if (!type)
   790         return;
   791 
   792     type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
   793     if (!type)
   794         return;
   795 
   796     node->setType(type);
   797 }
   798 
   799 void
   800 SemanticAnalysis::visit(FloatLiteral *node)
   801 {
   802     Type *type = zone_->types()->getPrimitive(PrimitiveType_Float);
   803     if (!type)
   804         return;
   805 
   806     node->setType(type);
   807 }
   808 
   809 void
   810 SemanticAnalysis::visit(BreakStatement *node)
   811 {
   812     if (loopDepth_ == 0)
   813         cc_.reportError(node->pos(), Message_BreakOutsideLoop);
   814 }
   815 
   816 void
   817 SemanticAnalysis::visit(ContinueStatement *node)
   818 {
   819     if (loopDepth_ == 0)
   820         cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
   821 }