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