ExprNodePtr SizeNode::evaluate (LContext &lcontext) { obj = obj->evaluate(lcontext); ArrayTypePtr arrayType = obj->type.cast<ArrayType>(); if( !arrayType) { return lcontext.newIntLiteralNode (lineNumber, 1); } else if( arrayType->size() != 0 ) { return lcontext.newIntLiteralNode (lineNumber, arrayType->size()); } return this; }
ExprNodePtr ArrayIndexNode::evaluate (LContext &lcontext) { IntTypePtr intType = lcontext.newIntType (); array = array->evaluate (lcontext); index = index->evaluate (lcontext); if( IntLiteralNodePtr literal = index.cast<IntLiteralNode>()) { if(literal->value < 0) { string name = ""; if( NameNodePtr arrayName = array.cast<NameNode>() ) name = arrayName->name; MESSAGE_LE (lcontext, ERR_ARR_IND_TYPE, array->lineNumber, "Index into array " << name << " is negative " "(" << literal->value << ")."); } ArrayTypePtr arrayType = array->type.cast<ArrayType>(); if(!arrayType) return this; if( literal->value >= arrayType->size() && arrayType->size() != 0) { string name = ""; if( NameNodePtr arrayName = array.cast<NameNode>() ) name = arrayName->name; MESSAGE_LE (lcontext, ERR_ARR_IND_TYPE, array->lineNumber, "Index into array " << name << " is out of range " "(index = " << literal->value << ", " "array size = " << arrayType->size() << ")."); } } if (index->type && !intType->isSameTypeAs (index->type)) index = intType->castValue (lcontext, index); return this; }