Added array support back.
Added array support back.
1.1 --- a/src/Messages.tbl Sat Nov 17 23:13:39 2012 -0800
1.2 +++ b/src/Messages.tbl Sun Nov 18 14:53:23 2012 -0800
1.3 @@ -7,7 +7,7 @@
1.4 MSG(ExpectedExpression, SyntaxError, "expected expression, got '%s'")
1.5 MSG(RedeclaredName, SyntaxError, "name '%s' was redeclared (previous at line %d, col %d)")
1.6 MSG(ExpectedLValue, SyntaxError, "impossible assignment, expected l-value")
1.7 -MSG(MaximumArrayDepth, SyntaxError, "maximum array dimension depth exceeded")
1.8 +MSG(MaximumArrayDepth, TypeError, "maximum array dimension depth exceeded")
1.9 MSG(ArrayInitializerDepth, SyntaxError, "array declaration and initializer have different dimension counts")
1.10 MSG(BadArraySize, SyntaxError, "array size must be positive")
1.11 MSG(ArraySizeTooBig, SyntaxError, "array size is too big")
2.1 --- a/src/Types.cpp Sat Nov 17 23:13:39 2012 -0800
2.2 +++ b/src/Types.cpp Sun Nov 18 14:53:23 2012 -0800
2.3 @@ -63,6 +63,13 @@
2.4 ArrayType *
2.5 ArrayType::New(Zone *zone, Handle<Type> contained, int elements)
2.6 {
2.7 + if (contained->isArray() &&
2.8 + ArrayType::cast(contained)->levels() == MAX_ARRAY_DEPTH)
2.9 + {
2.10 + zone->reportError(Message_MaximumArrayDepth);
2.11 + return NULL;
2.12 + }
2.13 +
2.14 Local<ArrayType> type(zone, ArrayType::cast(zone->allocate(MapKind_ArrayType, sizeof(ArrayType), Heap::Tenure_Old)));
2.15 if (!type)
2.16 return NULL;
2.17 @@ -201,7 +208,6 @@
2.18 }
2.19 }
2.20
2.21 -
2.22 StructType *
2.23 StructType::New(Zone *zone, Handle<String> name, Handle<FixedArray> fields)
2.24 {
3.1 --- a/src/Types.h Sat Nov 17 23:13:39 2012 -0800
3.2 +++ b/src/Types.h Sun Nov 18 14:53:23 2012 -0800
3.3 @@ -100,9 +100,7 @@
3.4 return kind_;
3.5 }
3.6
3.7 - public:
3.8 - static const int DYNAMIC_ARRAY_SIZE = -1;
3.9 -
3.10 + public:
3.11 static Type *NewVoid(Zone *zone);
3.12 static Type *NewUnchecked(Zone *zone);
3.13 static Type *NewPrimitive(Zone *zone, PrimitiveType type);
3.14 @@ -156,6 +154,9 @@
3.15 : primitive()
3.16 : PrimitiveType_Int32;
3.17 }
3.18 + bool isChar() {
3.19 + return isPrimitive() && primitive() == PrimitiveType_Char;
3.20 + }
3.21 bool isFloat() {
3.22 return isPrimitive() && primitive() == PrimitiveType_Float;
3.23 }
3.24 @@ -213,6 +214,8 @@
3.25 class ArrayType : public Type
3.26 {
3.27 public:
3.28 + static const int DYNAMIC_ARRAY_SIZE = -1;
3.29 +
3.30 static ArrayType *New(Zone *zone, Handle<Type> contained, int elements);
3.31 static ArrayType *NewExternal(Zone *zone, Handle<Type> contained);
3.32
4.1 --- a/src/compiler/ConstantEvaluator.cpp Sat Nov 17 23:13:39 2012 -0800
4.2 +++ b/src/compiler/ConstantEvaluator.cpp Sun Nov 18 14:53:23 2012 -0800
4.3 @@ -0,0 +1,92 @@
4.4 +/* vim: set ts=4 sw=4 tw=99 et:
4.5 + *
4.6 + * Copyright (C) 2012 David Anderson
4.7 + *
4.8 + * This file is part of SourcePawn.
4.9 + *
4.10 + * SourcePawn is free software: you can redistribute it and/or modify it under
4.11 + * the terms of the GNU General Public License as published by the Free
4.12 + * Software Foundation, either version 3 of the License, or (at your option)
4.13 + * any later version.
4.14 + *
4.15 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
4.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
4.18 + *
4.19 + * You should have received a copy of the GNU General Public License along with
4.20 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
4.21 + */
4.22 +#include "AST.h"
4.23 +#include "ConstantEvaluator.h"
4.24 +
4.25 +using namespace ke;
4.26 +
4.27 +static inline bool
4.28 +EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
4.29 + BoxedPrimitive *out)
4.30 +{
4.31 + switch (kind) {
4.32 + case TOK_PLUS:
4.33 + *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
4.34 + return true;
4.35 +
4.36 + case TOK_SHL:
4.37 + *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
4.38 + return true;
4.39 +
4.40 + default:
4.41 + return false;
4.42 + }
4.43 +}
4.44 +
4.45 +static inline bool
4.46 +EvaluateUnaryOperation(TokenKind kind, const BoxedPrimitive &inner, BoxedPrimitive *out)
4.47 +{
4.48 + switch (kind) {
4.49 + case TOK_MINUS:
4.50 + *out = BoxedPrimitive::Int(-inner.toInt());
4.51 + return true;
4.52 +
4.53 + default:
4.54 + return false;
4.55 + }
4.56 +}
4.57 +
4.58 +bool
4.59 +ke::EvaluateForConstant(Expression *expr, BoxedPrimitive *out)
4.60 +{
4.61 + switch (expr->kind()) {
4.62 + case AstNode::kBinaryExpression:
4.63 + {
4.64 + BoxedPrimitive left;
4.65 + BoxedPrimitive right;
4.66 + BinaryExpression *b = expr->toBinaryExpression();
4.67 + if (!EvaluateForConstant(b->left(), &left) ||
4.68 + !EvaluateForConstant(b->right(), &right))
4.69 + {
4.70 + return false;
4.71 + }
4.72 + return EvaluateBinaryOperation(b->token(), left, right, out);
4.73 + }
4.74 +
4.75 + case AstNode::kUnaryExpression:
4.76 + {
4.77 + BoxedPrimitive inner;
4.78 + UnaryExpression *u = expr->toUnaryExpression();
4.79 + if (!EvaluateForConstant(u->expression(), &inner))
4.80 + return false;
4.81 + return EvaluateUnaryOperation(u->token(), inner, out);
4.82 + }
4.83 +
4.84 + case AstNode::kBooleanLiteral:
4.85 + *out = BoxedPrimitive::Int(expr->toBooleanLiteral()->token() == TOK_TRUE ? 1 : 0);
4.86 + return true;
4.87 +
4.88 + case AstNode::kIntegerLiteral:
4.89 + *out = BoxedPrimitive::Int(expr->toIntegerLiteral()->value());
4.90 + return true;
4.91 +
4.92 + default:
4.93 + return false;
4.94 + }
4.95 +}
5.1 --- a/src/compiler/HIR.cpp Sat Nov 17 23:13:39 2012 -0800
5.2 +++ b/src/compiler/HIR.cpp Sun Nov 18 14:53:23 2012 -0800
5.3 @@ -44,6 +44,7 @@
5.4 void visitLocal(HLocal *local);
5.5 void visitGlobal(HGlobal *global);
5.6 void visitConvert(HConvert *convert);
5.7 + void visitIndex(HIndex *index);
5.8
5.9 private:
5.10 Zone *zone_;
5.11 @@ -151,6 +152,13 @@
5.12 }
5.13
5.14 void
5.15 +HIRTranslator::visitIndex(HIndex *index)
5.16 +{
5.17 + index->bind(this, emitter_);
5.18 + index->load(emitter_);
5.19 +}
5.20 +
5.21 +void
5.22 HIRTranslator::visitGlobal(HGlobal *global)
5.23 {
5.24 __ getglobal(global->sym());
6.1 --- a/src/compiler/NameBinding.cpp Sat Nov 17 23:13:39 2012 -0800
6.2 +++ b/src/compiler/NameBinding.cpp Sun Nov 18 14:53:23 2012 -0800
6.3 @@ -194,7 +194,8 @@
6.4 // And we don't necessarily want this to bind.
6.5 }
6.6
6.7 - node->initialization()->accept(this);
6.8 + if (node->initialization())
6.9 + node->initialization()->accept(this);
6.10 }
6.11 void visitEnumStatement(EnumStatement *node) {
6.12 assert(false);
6.13 @@ -318,7 +319,8 @@
6.14 node->ifFalse()->accept(this);
6.15 }
6.16 void visitIndexExpression(IndexExpression *node) {
6.17 - assert(false);
6.18 + node->left()->accept(this);
6.19 + node->right()->accept(this);
6.20 }
6.21 void visitFloatLiteral(FloatLiteral *node) {
6.22 }
6.23 @@ -424,6 +426,10 @@
6.24 return populator.analyze();
6.25 }
6.26
6.27 +static const int INFER_ARRAY_SIZE = 0;
6.28 +static const int EVAL_ARRAY_SIZE = -1;
6.29 +static const int DYNAMIC_ARRAY_SIZE = -2;
6.30 +
6.31 class NameBinder : public AstVisitor
6.32 {
6.33 public:
6.34 @@ -487,14 +493,37 @@
6.35 void visitVariableDeclaration(VariableDeclaration *node) {
6.36 // Bind the initializer before registering the declaration, so that we
6.37 // can error on bogus initializers (new x = x).
6.38 - node->initialization()->accept(this);
6.39 + if (node->initialization())
6.40 + node->initialization()->accept(this);
6.41
6.42 Local<Type> type(zone_, bindType(node->type()));
6.43 if (!type)
6.44 return;
6.45
6.46 - if (node->dims()) {
6.47 -
6.48 + if (node->dims() || type->isArray()) {
6.49 + int dims[MAX_ARRAY_DEPTH];
6.50 + int levels = evaluateDimensions(node->pos(), type, node->dims(), dims);
6.51 + if (levels < 0)
6.52 + return;
6.53 +
6.54 + // Do some extra inference based on the initializer, if present.
6.55 + Expression *init = node->initialization();
6.56 + if (init &&
6.57 + init->isArrayLiteral() &&
6.58 + init->toArrayLiteral()->isFixed())
6.59 + {
6.60 + Local<Type> contained(zone_, type->isArray()
6.61 + ? ArrayType::cast(type)->contained()
6.62 + : type);
6.63 + if (!inferFixedArrayDimensions(init->toArrayLiteral(), contained, dims, levels))
6.64 + return;
6.65 + }
6.66 +
6.67 + // If we got extra dimensions, we need to build a new type.
6.68 + if (node->dims()) {
6.69 + if ((type = buildArrayType(type, dims, node->dims()->length())) == NULL)
6.70 + return;
6.71 + }
6.72 }
6.73
6.74 // If the node already has a symbol (meaning it was a global), then
6.75 @@ -654,6 +683,109 @@
6.76 }
6.77
6.78 private:
6.79 + int evaluateDimensions(const SourcePosition &pos, Handle<Type> typeArg, ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH]) {
6.80 + unsigned level = 0;
6.81 + Local<Type> type(zone_, typeArg);
6.82 + while (type->isArray()) {
6.83 + ArrayType *atype = ArrayType::cast(type);
6.84 + dims[level] = atype->isFixedLength()
6.85 + ? atype->fixedLength()
6.86 + : DYNAMIC_ARRAY_SIZE;
6.87 + type = atype->contained();
6.88 + level++;
6.89 + }
6.90 +
6.91 + if (!exprs)
6.92 + return level;
6.93 +
6.94 + if (level + exprs->length() > MAX_ARRAY_DEPTH) {
6.95 + cc_.reportError(pos, Message_MaximumArrayDepth);
6.96 + return -1;
6.97 + }
6.98 +
6.99 + bool hadEmptySize = false;
6.100 + for (size_t i = 0; i < exprs->length(); i++) {
6.101 + Expression *expr = exprs->at(i);
6.102 + if (!expr) {
6.103 + dims[i] = INFER_ARRAY_SIZE;
6.104 + hadEmptySize = true;
6.105 + continue;
6.106 + }
6.107 +
6.108 + BoxedPrimitive box;
6.109 + if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
6.110 + int size = box.toInt();
6.111 + if (size <= 0) {
6.112 + cc_.reportError(expr->pos(), Message_BadArraySize);
6.113 + return false;
6.114 + }
6.115 +
6.116 + dims[i] = size;
6.117 + continue;
6.118 + }
6.119 +
6.120 + if (hadEmptySize) {
6.121 + cc_.reportError(expr->pos(), Message_BadDynamicInitializer);
6.122 + return false;
6.123 + }
6.124 +
6.125 + dims[i] = EVAL_ARRAY_SIZE;
6.126 + }
6.127 +
6.128 + return level + exprs->length();
6.129 + }
6.130 +
6.131 + // This function computes missing dimension sizes based on a literal
6.132 + // initializer. We don't really handle any size rules here; we just
6.133 + // do a really dumb inference.
6.134 + bool inferFixedArrayDimensions(ArrayLiteral *lit, Handle<Type> contained, int dims[MAX_ARRAY_DEPTH], int levels) {
6.135 + for (int i = 0; i < levels; i++) {
6.136 + if (dims[i] == EVAL_ARRAY_SIZE || dims[i] == DYNAMIC_ARRAY_SIZE) {
6.137 + // The following are invalid:
6.138 + // new x[<expr>] = {...}
6.139 + // new Type:x = {...} // where Type is a non-fixed array type
6.140 + cc_.reportError(lit->pos(), Message_CannotInitializeEvalArray);
6.141 + return false;
6.142 + }
6.143 +
6.144 + if (dims[i] == INFER_ARRAY_SIZE) {
6.145 + // Character arrays are always dynamic when inferred from string literals.
6.146 + if (i == levels - 1 && contained->isChar())
6.147 + dims[i] = DYNAMIC_ARRAY_SIZE;
6.148 + else
6.149 + dims[i] = lit->expressions()->length();
6.150 + }
6.151 +
6.152 + if (i != levels - 1) {
6.153 + // Fixed array literals are guaranteed to have at least one expression.
6.154 + Expression *next = lit->expressions()->at(0);
6.155 + if (!next->isArrayLiteral()) {
6.156 + // Whelp... this array is just malformed. Not the best error message
6.157 + // but whatever.
6.158 + cc_.reportError(next->pos(), Message_ArraySizeCannotBeDetermined);
6.159 + return false;
6.160 + }
6.161 + lit = next->toArrayLiteral();
6.162 + }
6.163 + }
6.164 +
6.165 + return true;
6.166 + }
6.167 +
6.168 + ArrayType *buildArrayType(Handle<Type> contained, int dims[MAX_ARRAY_DEPTH], size_t postlevels) {
6.169 + Local<Type> type(zone_, contained);
6.170 + for (size_t i = postlevels - 1; i < postlevels; i--) {
6.171 + int size = dims[i] > 0
6.172 + ? dims[i]
6.173 + : ArrayType::DYNAMIC_ARRAY_SIZE;
6.174 +
6.175 + type = zone_->types()->newArray(contained, size);
6.176 + if (!type)
6.177 + return NULL;
6.178 + }
6.179 + return ArrayType::cast(type);
6.180 + }
6.181 +
6.182 bool fillFunctionType(Handle<FunctionType> fun, const FunctionSignature &sig) {
6.183 Local<Type> type(zone_);
6.184 if (!fun->returnType()) {
7.1 --- a/src/compiler/Parser.cpp Sat Nov 17 23:13:39 2012 -0800
7.2 +++ b/src/compiler/Parser.cpp Sun Nov 18 14:53:23 2012 -0800
7.3 @@ -139,30 +139,21 @@
7.4 }
7.5
7.6 Expression *
7.7 -Parser::arrayLiteral(TokenKind kind)
7.8 +Parser::fixedArrayLiteral()
7.9 {
7.10 - assert(kind == TOK_LBRACE || kind == TOK_LBRACKET);
7.11 -
7.12 - TokenKind close = (kind == TOK_LBRACE)
7.13 - ? TOK_RBRACE
7.14 - : TOK_RBRACKET;
7.15 -
7.16 SourcePosition pos = scanner_.begin();
7.17
7.18 ExpressionList *list = new (pool_) ExpressionList();
7.19 do {
7.20 - if (match(close))
7.21 + // { } is an illegal array literal.
7.22 + if (list->length() > 0 && match(TOK_LBRACE))
7.23 break;
7.24
7.25 Expression *expr = NULL;
7.26 - if (kind == TOK_LBRACE) {
7.27 - if (peek(TOK_LBRACE))
7.28 - expr = arrayLiteral(TOK_LBRACE);
7.29 - else
7.30 - expr = primitive();
7.31 - } else {
7.32 - expr = expression();
7.33 - }
7.34 + if (peek(TOK_LBRACE))
7.35 + expr = fixedArrayLiteral();
7.36 + else
7.37 + expr = primitive();
7.38 if (!expr)
7.39 return NULL;
7.40
7.41 @@ -170,13 +161,13 @@
7.42 return NULL;
7.43
7.44 if (!match(TOK_COMMA)) {
7.45 - if (!expect(close))
7.46 + if (!expect(TOK_RBRACE))
7.47 return NULL;
7.48 break;
7.49 }
7.50 } while (true);
7.51
7.52 - return new (pool_) ArrayLiteral(pos, kind, list);
7.53 + return new (pool_) ArrayLiteral(pos, TOK_LBRACE, list);
7.54 }
7.55
7.56 Expression *
7.57 @@ -882,7 +873,7 @@
7.58 return NULL;
7.59
7.60 ExpressionList *dims = NULL;
7.61 - if (match(TOK_LBRACE)) {
7.62 + if (peek(TOK_LBRACKET)) {
7.63 if ((dims = dimensions()) == NULL)
7.64 return NULL;;
7.65 }
7.66 @@ -894,7 +885,8 @@
7.67 switch (scanner_.peek()) {
7.68 // Note: we don't support [] literals yet.
7.69 case TOK_LBRACE:
7.70 - if ((expr = arrayLiteral(scanner_.scan())) == NULL)
7.71 + scanner_.scan();
7.72 + if ((expr = fixedArrayLiteral()) == NULL)
7.73 return NULL;
7.74 break;
7.75
8.1 --- a/src/compiler/Parser.h Sat Nov 17 23:13:39 2012 -0800
8.2 +++ b/src/compiler/Parser.h Sun Nov 18 14:53:23 2012 -0800
8.3 @@ -59,7 +59,7 @@
8.4 String *expectName();
8.5
8.6 Expression *primitive();
8.7 - Expression *arrayLiteral(TokenKind kind);
8.8 + Expression *fixedArrayLiteral();
8.9 Expression *call(Expression *callee);
8.10 Expression *field(Expression *left);
8.11 Expression *index(Expression *left);
9.1 --- a/src/compiler/SemanticAnalysis.cpp Sat Nov 17 23:13:39 2012 -0800
9.2 +++ b/src/compiler/SemanticAnalysis.cpp Sun Nov 18 14:53:23 2012 -0800
9.3 @@ -292,24 +292,56 @@
9.4 assert(__ stackDepth() == 0);
9.5 }
9.6
9.7 +static inline Heap::Tenure
9.8 +InferTenure(Symbol *sym)
9.9 +{
9.10 + if (sym->scope()->kind() == Scope::GLOBAL)
9.11 + return Heap::Tenure_Old;
9.12 + // :TODO: need to use LIFO!
9.13 + return Heap::Tenure_Default;
9.14 +}
9.15 +
9.16 void
9.17 SemanticAnalysis::visitVariableDeclaration(VariableDeclaration *node)
9.18 {
9.19 PoolScope poolScope(zone_->pool());
9.20 RootScope rootScope(zone_);
9.21
9.22 - HIR *hir = NULL;
9.23 if (node->initialization()) {
9.24 + HIR *hir = NULL;
9.25 +
9.26 if ((hir = eval(node->initialization())) == NULL)
9.27 return;
9.28 if ((hir = coerce(hir, node->sym()->type(), Coerce_Assign)) == NULL)
9.29 return;
9.30 +
9.31 + discharge(hir);
9.32 } else {
9.33 - assert(false);
9.34 + if (node->sym()->type()->isInt32() ||
9.35 + node->sym()->type()->isEnum() ||
9.36 + node->sym()->type()->isChar() ||
9.37 + node->sym()->type()->isBool())
9.38 + {
9.39 + __ int_(0);
9.40 + } else if (node->sym()->type()->isFloat()) {
9.41 + __ float_(0);
9.42 + } else if (node->sym()->type()->isArray()) {
9.43 + Local<ArrayType> type(zone_, ArrayType::cast(node->sym()->type()));
9.44 + Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, type));
9.45 + if (!map)
9.46 + return;
9.47 +
9.48 + if (type->isFixedLength()) {
9.49 + __ newarray(OP_NEWFIXED, map, InferTenure(node->sym()));
9.50 + } else if (node->dims()) {
9.51 + assert(false);
9.52 + __ newarray(OP_NEWSIZED, map, InferTenure(node->sym()));
9.53 + } else {
9.54 + __ newarray(OP_NEWEMPTY, map, InferTenure(node->sym()));
9.55 + }
9.56 + }
9.57 }
9.58
9.59 - discharge(hir);
9.60 -
9.61 if (!__ allocate(node->sym()))
9.62 return;
9.63
9.64 @@ -524,6 +556,33 @@
9.65 __ jump(loop_->continue_());
9.66 }
9.67
9.68 +void
9.69 +SemanticAnalysis::visitIndexExpression(IndexExpression *node)
9.70 +{
9.71 + HIR *left = eval(node->left());
9.72 + if (!left)
9.73 + return;
9.74 +
9.75 + HIR *right = eval(node->right());
9.76 + if (!right)
9.77 + return;
9.78 +
9.79 + // Hrm... yes, for now, let's coerce here.
9.80 + Local<Type> i32(zone_, zone_->types()->getPrimitive(PrimitiveType_Int32));
9.81 + if ((right = coerce(right, i32, Coerce_Arg)) == NULL)
9.82 + return;
9.83 +
9.84 + // Do not coerce here, there's no reason to yet.
9.85 + if (!left->type()->isArray()) {
9.86 + cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
9.87 + return;
9.88 + }
9.89 +
9.90 + hir_ = new (pool_) HIndex(ArrayType::cast(left->type())->contained(),
9.91 + left,
9.92 + right);
9.93 +}
9.94 +
9.95 Type *
9.96 SemanticAnalysis::coercionType(TokenKind token, HIR *left, HIR *right)
9.97 {
10.1 --- a/src/compiler/SemanticAnalysis.h Sat Nov 17 23:13:39 2012 -0800
10.2 +++ b/src/compiler/SemanticAnalysis.h Sun Nov 18 14:53:23 2012 -0800
10.3 @@ -61,6 +61,7 @@
10.4 void visitBreakStatement(BreakStatement *node);
10.5 void visitContinueStatement(ContinueStatement *node);
10.6 void visitIfStatement(IfStatement *node);
10.7 + void visitIndexExpression(IndexExpression *node);
10.8 #if 0
10.9 void visitFunctionTypeStatement(FunctionTypeStatement *node);
10.10 void visitImportStatement(ImportStatement *node);
10.11 @@ -71,7 +72,6 @@
10.12
10.13 void visitBinaryExpression(BinaryExpression *node);
10.14 void visitCallExpression(CallExpression *node);
10.15 - void visitIndexExpression(IndexExpression *node);
10.16 void visitStringLiteral(StringLiteral *node);
10.17 void visitIncDecExpression(IncDecExpression *node);
10.18 void visitUnaryExpression(UnaryExpression *node);
11.1 --- a/src/jitcraft.vcxproj Sat Nov 17 23:13:39 2012 -0800
11.2 +++ b/src/jitcraft.vcxproj Sun Nov 18 14:53:23 2012 -0800
11.3 @@ -99,6 +99,7 @@
11.4 <ClCompile Include="Box.cpp" />
11.5 <ClCompile Include="compiler\BytecodeEmitter.cpp" />
11.6 <ClCompile Include="compiler\CompileContext.cpp" />
11.7 + <ClCompile Include="compiler\ConstantEvaluator.cpp" />
11.8 <ClCompile Include="compiler\HIR.cpp" />
11.9 <ClCompile Include="compiler\NameBinding.cpp" />
11.10 <ClCompile Include="compiler\Parser.cpp" />
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/tests/basic/float-arrays.out Sun Nov 18 14:53:23 2012 -0800
12.3 @@ -0,0 +1,1 @@
12.4 +11.500000
13.1 --- a/tests/basic/float-arrays.sp Sat Nov 17 23:13:39 2012 -0800
13.2 +++ b/tests/basic/float-arrays.sp Sun Nov 18 14:53:23 2012 -0800
13.3 @@ -1,4 +1,4 @@
13.4 -native PrintFloat(Float:num);
13.5 +native PrintFloat(float:num);
13.6
13.7 public main()
13.8 {