jitcraft/SemanticAnalysis.cpp
changeset 14 0784ac5cc347
parent 12 75e385f68b7e
child 17 8aa89dd41e25
     1.1 --- a/jitcraft/SemanticAnalysis.cpp	Sat Jun 30 20:20:39 2012 -0700
     1.2 +++ b/jitcraft/SemanticAnalysis.cpp	Sat Jun 30 22:31:14 2012 -0700
     1.3 @@ -120,8 +120,12 @@
     1.4  SemanticAnalysis::visitForLoad(Expression *expression)
     1.5  {
     1.6      expression->accept(this);
     1.7 -    if (expression->type() && expression->type()->isArray())
     1.8 -        expression->setType(expression->type()->contained());
     1.9 +    if (expression->type()) {
    1.10 +        // :TODO: use Local
    1.11 +        Type *type = expression->type();
    1.12 +        if (type->isArray() || type->isReference())
    1.13 +            expression->setType(type->contained());
    1.14 +    }
    1.15      return expression->type();
    1.16  }
    1.17  
    1.18 @@ -163,7 +167,10 @@
    1.19          }
    1.20  
    1.21          Variable *var = proxy->binding()->toVariable();
    1.22 -        node->setType(var->type());
    1.23 +        if  (var->type()->isReference())
    1.24 +            node->setType(var->type()->contained());
    1.25 +        else
    1.26 +            node->setType(var->type());
    1.27      }
    1.28  
    1.29      assert(TypeCheck(node->type(), node->expression()->type()));
    1.30 @@ -247,6 +254,7 @@
    1.31  void
    1.32  SemanticAnalysis::visit(VariableDeclaration *node)
    1.33  {
    1.34 +    // :TODO: use locals
    1.35      Type *type = ZONE()->types()->getPrimitiveForTag(node->tag());
    1.36      if (!type)
    1.37          return;
    1.38 @@ -308,17 +316,100 @@
    1.39      node->expression()->accept(this);
    1.40  }
    1.41  
    1.42 +bool
    1.43 +SemanticAnalysis::preanalyze(FunctionStatement *node)
    1.44 +{
    1.45 +    // :TODO: use Local
    1.46 +
    1.47 +    FixedArray *args = FixedArray::New(ZONE(), node->parameters()->size(), Heap::Tenure_Old);
    1.48 +    if (!args)
    1.49 +        return false;
    1.50 +
    1.51 +    // Apply types to arguments.
    1.52 +    for (size_t i = 0; i < node->parameters()->size(); i++) {
    1.53 +        Parameter *parameter = node->parameters()->at(i);
    1.54 +        
    1.55 +        Type *type = ZONE()->types()->getPrimitiveForTag(parameter->tag());
    1.56 +        if (!type)
    1.57 +            return false;
    1.58 +
    1.59 +        if (parameter->reference()) {
    1.60 +            type = ZONE()->types()->getReference(type);
    1.61 +            if (!type)
    1.62 +                return false;
    1.63 +        }
    1.64 +
    1.65 +        args->set(ZONE(), i, type);
    1.66 +        parameter->variable()->setType(type);
    1.67 +    }
    1.68 +
    1.69 +    Type *returnType = ZONE()->types()->getPrimitive(PrimitiveType_Int32);
    1.70 +    if (!returnType)
    1.71 +        return false;
    1.72 +
    1.73 +    Type *funtype = ZONE()->types()->newFunction(returnType, args);
    1.74 +    if (!funtype)
    1.75 +        return false;
    1.76 +
    1.77 +    node->fun()->setType(funtype);
    1.78 +    return true;
    1.79 +}
    1.80 +
    1.81  void
    1.82  SemanticAnalysis::visit(FunctionStatement *node)
    1.83  {
    1.84      scope_ = node->scope();
    1.85 +
    1.86 +    // :TODO: call this ahead of time.
    1.87 +    if (!preanalyze(node))
    1.88 +        return;
    1.89 +
    1.90      node->body()->accept(this);
    1.91      scope_ = NULL;
    1.92  }
    1.93  
    1.94 +// :TODO: use handles
    1.95 +static inline bool
    1.96 +TypeCheckParameter(Type *given, Type *actual)
    1.97 +{
    1.98 +    if (actual->isReference()) {
    1.99 +        if (given->isReference())
   1.100 +            given = given->contained();
   1.101 +        return TypeCheck(given, actual->contained());
   1.102 +    }
   1.103 +
   1.104 +    return TypeCheck(given, actual);
   1.105 +}
   1.106 +
   1.107  void
   1.108  SemanticAnalysis::visit(CallExpression *node)
   1.109  {
   1.110 +    visitForLoad(node->callee());
   1.111 +
   1.112 +    // :TODO: use locals
   1.113 +    Type *type = node->callee()->type();
   1.114 +    if (!type)
   1.115 +        return;
   1.116 +
   1.117 +    assert(type->isFunction());
   1.118 +    assert(node->arguments()->size() == type->parameters()->length());
   1.119 +
   1.120 +    for (unsigned i = 0; i < node->arguments()->size(); i++) {
   1.121 +        Expression *expression = node->arguments()->at(i);
   1.122 +        expression->accept(this);
   1.123 +
   1.124 +        Type *given = expression->type();
   1.125 +        if (!given)
   1.126 +            return;
   1.127 +
   1.128 +        Type *actual = Type::cast(type->parameters()->at(i));
   1.129 +        assert(TypeCheckParameter(given, actual));
   1.130 +
   1.131 +        // If the actual is a reference, and the given is not, we'll need to
   1.132 +        // compute a reference, which may be allocated on the stack.
   1.133 +        if (actual->isReference() && !given->isReference())
   1.134 +            scope_->setUsesLifoHeap();
   1.135 +    }
   1.136  }
   1.137  
   1.138  void
   1.139 @@ -333,6 +424,7 @@
   1.140  void
   1.141  SemanticAnalysis::visit(IndexExpression *node)
   1.142  {
   1.143 +    // :TODO: use locals
   1.144      Type *left = visitForRef(node->left());
   1.145      Type *right = visitForLoad(node->right());
   1.146