1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/jitcraft/SemanticAnalysis.cpp Mon Jun 25 02:57:28 2012 -0700
1.3 @@ -0,0 +1,200 @@
1.4 +/*
1.5 + * Copyright (C) 2012 David Anderson
1.6 + *
1.7 + * This file is part of JITCraft.
1.8 + *
1.9 + * JITCraft is free software: you can redistribute it and/or modify it under
1.10 + * the terms of the GNU General Public License as published by the Free
1.11 + * Software Foundation, either version 3 of the License, or (at your option)
1.12 + * any later version.
1.13 + *
1.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
1.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.17 + *
1.18 + * You should have received a copy of the GNU General Public License along with
1.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
1.20 + */
1.21 +#include "SemanticAnalysis.h"
1.22 +#include "Types.h"
1.23 +
1.24 +using namespace jc;
1.25 +
1.26 +SemanticAnalysis::SemanticAnalysis(ParseTree *tree)
1.27 + : tree_(tree)
1.28 +{
1.29 +}
1.30 +
1.31 +bool
1.32 +SemanticAnalysis::analyze()
1.33 +{
1.34 + for (size_t i = 0; i < tree_->statements()->length(); i++) {
1.35 + Statement *statement = tree_->statements()->at(i);
1.36 + statement->accept(this);
1.37 + }
1.38 +
1.39 + return true;
1.40 +}
1.41 +
1.42 +void
1.43 +SemanticAnalysis::visit(NameProxy *name)
1.44 +{
1.45 + name->setType(name->binding()->type());
1.46 +}
1.47 +
1.48 +static inline bool
1.49 +IsPrimitiveType(Type *type, PrimitiveType primitive)
1.50 +{
1.51 + if (!type)
1.52 + return false;
1.53 +
1.54 + if (!type->isPrimitive())
1.55 + return false;
1.56 +
1.57 + return primitive == type->primitive();
1.58 +}
1.59 +
1.60 +void
1.61 +SemanticAnalysis::visit(Assignment *node)
1.62 +{
1.63 + node->expression()->accept(this);
1.64 +
1.65 + if (node->lvalue()->isIndexExpression()) {
1.66 + node->lvalue()->accept(this);
1.67 +
1.68 + node->setType(node->lvalue()->type());
1.69 + } else {
1.70 + NameProxy *proxy = node->lvalue()->toNameProxy();
1.71 + if (!proxy->binding()->kind() == BoundName::VARIABLE) {
1.72 + fprintf(stderr, "error\n");
1.73 + return;
1.74 + }
1.75 +
1.76 + Variable *var = proxy->binding()->toVariable();
1.77 + node->setType(var->type());
1.78 + }
1.79 +}
1.80 +
1.81 +void
1.82 +SemanticAnalysis::visit(BinaryExpression *node)
1.83 +{
1.84 +}
1.85 +
1.86 +void
1.87 +SemanticAnalysis::visit(ReturnStatement *node)
1.88 +{
1.89 + node->expression()->accept(this);
1.90 +
1.91 + // :TODO: type check
1.92 +}
1.93 +
1.94 +void
1.95 +SemanticAnalysis::visit(ForStatement *node)
1.96 +{
1.97 + if (node->declaration())
1.98 + node->declaration()->accept(this);
1.99 + if (node->condition())
1.100 + node->condition()->accept(this);
1.101 + if (node->update())
1.102 + node->update()->accept(this);
1.103 + node->body()->accept(this);
1.104 +}
1.105 +
1.106 +void
1.107 +SemanticAnalysis::visit(BlockStatement *node)
1.108 +{
1.109 + for (size_t i = 0; i < node->statements()->length(); i++) {
1.110 + Statement *statement = node->statements()->at(i);
1.111 + statement->accept(this);
1.112 + }
1.113 +}
1.114 +
1.115 +void
1.116 +SemanticAnalysis::visit(VariableDeclaration *node)
1.117 +{
1.118 + Tag *tag = NULL;
1.119 +
1.120 + Type *type = Type::NewPrimitive(tag);
1.121 + if (!type)
1.122 + return;
1.123 +
1.124 + if (node->postDimensions()) {
1.125 + if (node->postDimensions()->size() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
1.126 + error();
1.127 + return;
1.128 + }
1.129 +
1.130 + for (size_t i = node->postDimensions()->size() - 1; i < node->postDimensions()->size(); i--) {
1.131 + Expression *expr = node->postDimensions()->at(i);
1.132 + expr->accept(this);
1.133 +
1.134 + if (!IsPrimitiveType(expr->type(), PrimitiveType_Int32)) {
1.135 + typeError(expr, "integer");
1.136 + return;
1.137 + }
1.138 +
1.139 + int size = -1;
1.140 + if (expr->isIntegerLiteralExpression()) {
1.141 + size = expr->toIntegerLiteralExpression()->value();
1.142 + if (size <= 0) {
1.143 + error();
1.144 + return;
1.145 + }
1.146 + if (size >= INT_MAX / sizeof(int)) {
1.147 + error();
1.148 + return;
1.149 + }
1.150 + }
1.151 +
1.152 + type = Type::NewUnsafeArray(type, size);
1.153 + }
1.154 + }
1.155 +
1.156 + node->variable()->setType(type);
1.157 +}
1.158 +
1.159 +void
1.160 +SemanticAnalysis::visit(IntegerLiteralExpression *node)
1.161 +{
1.162 + Type *type = Type::NewPrimitive(NULL);
1.163 + node->setType(type);
1.164 +}
1.165 +
1.166 +void
1.167 +SemanticAnalysis::visit(ExpressionStatement *node)
1.168 +{
1.169 + node->expression()->accept(this);
1.170 +}
1.171 +
1.172 +void
1.173 +SemanticAnalysis::visit(FunctionStatement *node)
1.174 +{
1.175 + node->body()->accept(this);
1.176 +}
1.177 +
1.178 +void
1.179 +SemanticAnalysis::visit(CallExpression *node)
1.180 +{
1.181 +}
1.182 +
1.183 +void
1.184 +SemanticAnalysis::visit(IfStatement *node)
1.185 +{
1.186 +}
1.187 +
1.188 +void
1.189 +SemanticAnalysis::visit(IndexExpression *node)
1.190 +{
1.191 + node->left()->accept(this);
1.192 + node->right()->accept(this);
1.193 +
1.194 + if (!node->right()->type(), PrimitiveType_Int32) {
1.195 + typeError(node->right(), "integer");
1.196 + return;
1.197 + }
1.198 + if (!node->left()->type() || !node->left()->type()->isArray()) {
1.199 + typeError(node->left(), "array");
1.200 + return;
1.201 + }
1.202 + node->setType(node->left()->type()->contained());
1.203 +}