1.1 --- a/src/SemanticAnalysis.cpp Sun Aug 12 20:51:31 2012 -0700
1.2 +++ b/src/SemanticAnalysis.cpp Sat Sep 01 16:36:20 2012 -0700
1.3 @@ -160,6 +160,11 @@
1.4 node->accept(this);
1.5 if (!node->decl()->type())
1.6 return false;
1.7 + } else if (statement->isFunctionTypeStatement()) {
1.8 + FunctionTypeStatement *node = statement->toFunctionTypeStatement();
1.9 + node->accept(this);
1.10 + if (!node->decl()->type())
1.11 + return false;
1.12 }
1.13 }
1.14
1.15 @@ -880,17 +885,18 @@
1.16 }
1.17
1.18 bool
1.19 -SemanticAnalysis::preanalyze(FunctionStatement *node)
1.20 +SemanticAnalysis::buildFunctionArgs(AstNode *node, TokenKind kind, const FunctionSignature &sig,
1.21 + FixedArray **argsp, FixedArray **defaultsp)
1.22 {
1.23 - Local<FixedArray> args(zone_, FixedArray::New(zone_, node->parameters()->length(), Heap::Tenure_Old));
1.24 + Local<FixedArray> args(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
1.25 if (!args)
1.26 return false;
1.27
1.28 Local<FixedArray> defaults(zone_);
1.29
1.30 // Apply types to arguments.
1.31 - for (size_t i = 0; i < node->parameters()->length(); i++) {
1.32 - Parameter *parameter = node->parameters()->at(i);
1.33 + for (size_t i = 0; i < sig.parameters()->length(); i++) {
1.34 + Parameter *parameter = sig.parameters()->at(i);
1.35
1.36 Local<Type> type(zone_, bindType(parameter->variable()->pos(), parameter->type()));
1.37 if (!type)
1.38 @@ -916,7 +922,7 @@
1.39 return false;
1.40 }
1.41
1.42 - if (node->fun()->isNative() && parameter->dimensions()->length() > 1) {
1.43 + if (kind == TOK_NATIVE && parameter->dimensions()->length() > 1) {
1.44 cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
1.45 return false;
1.46 }
1.47 @@ -951,7 +957,7 @@
1.48
1.49 if (parameter->initializer()) {
1.50 if (!defaults) {
1.51 - defaults = FixedArray::New(zone_, node->parameters()->length(), Heap::Tenure_Old);
1.52 + defaults = FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old);
1.53 if (!defaults)
1.54 return false;
1.55 }
1.56 @@ -964,12 +970,69 @@
1.57 }
1.58 }
1.59
1.60 + *argsp = args;
1.61 + *defaultsp = defaults;
1.62 +
1.63 + return true;
1.64 +}
1.65 +
1.66 +void
1.67 +SemanticAnalysis::visit(FunctionTypeStatement *node)
1.68 +{
1.69 + if (node->decl()->type())
1.70 + return;
1.71 +
1.72 + Local<FixedArray> args(zone_);
1.73 + Local<FixedArray> defaults(zone_);
1.74 +
1.75 + const FunctionSignature &sig= node->signature();
1.76 + if (!buildFunctionArgs(node,
1.77 + TOK_STOCK,
1.78 + sig,
1.79 + args.address(),
1.80 + defaults.address()))
1.81 + {
1.82 + return;
1.83 + }
1.84 +
1.85 Local<Type> returnType(zone_);
1.86 - if (node->returnType() ||
1.87 + if (sig.returnType())
1.88 + returnType = bindType(node->pos(), sig.returnType());
1.89 + else
1.90 + returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
1.91 +
1.92 + if (!returnType)
1.93 + return;
1.94 +
1.95 + Local<Type> funtype(zone_, zone_->types()->newFunction(returnType, args, defaults));
1.96 + if (!funtype)
1.97 + return;
1.98 +
1.99 + node->decl()->setType(funtype);
1.100 +}
1.101 +
1.102 +bool
1.103 +SemanticAnalysis::preanalyze(FunctionStatement *node)
1.104 +{
1.105 + Local<FixedArray> args(zone_);
1.106 + Local<FixedArray> defaults(zone_);
1.107 +
1.108 + const FunctionSignature &sig = node->signature();
1.109 + if (!buildFunctionArgs(node,
1.110 + node->fun()->token(),
1.111 + sig,
1.112 + args.address(),
1.113 + defaults.address()))
1.114 + {
1.115 + return false;
1.116 + }
1.117 +
1.118 + Local<Type> returnType(zone_);
1.119 + if (sig.returnType() ||
1.120 node->hasExplicitReturn() ||
1.121 node->fun()->isNative())
1.122 {
1.123 - returnType = bindType(node->pos(), node->returnType());
1.124 + returnType = bindType(node->pos(), sig.returnType());
1.125 } else {
1.126 returnType = zone_->types()->getVoid();
1.127 }
1.128 @@ -1118,6 +1181,14 @@
1.129 return false;
1.130 }
1.131
1.132 + if (given->isFunction() && actual->isFunction()) {
1.133 + if (!Type::Compare(given, actual)) {
1.134 + typeMismatch(pos, actual, given);
1.135 + return false;
1.136 + }
1.137 + return true;
1.138 + }
1.139 +
1.140 if (actual->isEnum()) {
1.141 if (!given->isEnum() || actual != given) {
1.142 typeMismatch(pos, actual, given);
1.143 @@ -1199,12 +1270,11 @@
1.144 return;
1.145 }
1.146
1.147 - // Currently, only calls from a NameProxy are possible.
1.148 - NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
1.149 - if (fun->isForward()) {
1.150 - cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
1.151 - return;
1.152 - }
1.153 + // NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
1.154 + // if (fun->isForward()) {
1.155 + // cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
1.156 + // return;
1.157 + // }
1.158
1.159 for (unsigned i = 0; i < node->arguments()->length(); i++) {
1.160 // Note: we don't compute references unless the callee needs a
1.161 @@ -1252,7 +1322,7 @@
1.162 scope_->setUsesLifoHeap();
1.163 }
1.164
1.165 - node->setType(fun->type()->returnType());
1.166 + node->setType(type->returnType());
1.167 }
1.168
1.169 void