diff options
Diffstat (limited to 'src/cljcc/analyze')
| -rw-r--r-- | src/cljcc/analyze/typecheck.clj | 66 |
1 files changed, 34 insertions, 32 deletions
diff --git a/src/cljcc/analyze/typecheck.clj b/src/cljcc/analyze/typecheck.clj index e042adc..52bc4e0 100644 --- a/src/cljcc/analyze/typecheck.clj +++ b/src/cljcc/analyze/typecheck.clj @@ -58,6 +58,8 @@ (defn- get-common-type [t1 t2] (cond (= t1 t2) t1 + (or (= t1 {:type :double}) + (= t2 {:type :double})) {:type :double} (= (u/get-type-size t1) (u/get-type-size t2)) (if (u/type-signed? t1) t2 @@ -78,20 +80,20 @@ (let [typed-left-e (typecheck-exp left ident->symbol) typed-right-e (typecheck-exp right ident->symbol)] - (if (t/logical? binary-operator) - (set-type (p/binary-exp-node typed-left-e - typed-right-e - binary-operator) - {:type :int}) - (let [tl (get-type typed-left-e) - tr (get-type typed-right-e) - common-type (get-common-type tl tr) - convert-left-exp (convert-to-exp typed-left-e common-type) - convert-right-exp (convert-to-exp typed-right-e common-type) - typed-binary-exp (p/binary-exp-node convert-left-exp convert-right-exp binary-operator)] - (if (t/arithmetic? binary-operator) - (set-type typed-binary-exp common-type) - (set-type typed-binary-exp {:type :int})))))) + (if (t/logical? binary-operator) + (set-type (p/binary-exp-node typed-left-e + typed-right-e + binary-operator) + {:type :int}) + (let [tl (get-type typed-left-e) + tr (get-type typed-right-e) + common-type (get-common-type tl tr) + convert-left-exp (convert-to-exp typed-left-e common-type) + convert-right-exp (convert-to-exp typed-right-e common-type) + typed-binary-exp (p/binary-exp-node convert-left-exp convert-right-exp binary-operator)] + (if (t/arithmetic? binary-operator) + (set-type typed-binary-exp common-type) + (set-type typed-binary-exp {:type :int})))))) (defmethod typecheck-exp :assignment-exp [{:keys [left right assignment-operator] :as _e} ident->symbol] @@ -101,7 +103,7 @@ left-type (get-type typed-left) converted-right (convert-to-exp typed-right left-type) typed-assign-exp (p/assignment-exp-node typed-left converted-right assignment-operator)] - (set-type typed-assign-exp left-type))) + (set-type typed-assign-exp left-type))) (defmethod typecheck-exp :conditional-exp [{:keys [left right middle] :as _e} m] @@ -118,21 +120,21 @@ [{:keys [identifier arguments] :as e} ident->symbol] (let [{ftype :type :as symbol} (get ident->symbol identifier)] - (if (symbol-function? symbol) - (let [_ (when (not= (count arguments) (count (:parameter-types ftype))) - (exc/analyzer-error "Function called with wrong number of arguments." - {:expected (count (:parameter-types ftype)) - :actual (count arguments)})) - cast-arg-to-param-type-f (fn [param-type arg] - (convert-to-exp (typecheck-exp arg ident->symbol) - param-type)) - converted-args (mapv cast-arg-to-param-type-f - (:parameter-types ftype) - arguments) - typed-fun-call-exp (p/function-call-exp-node identifier converted-args)] - (set-type typed-fun-call-exp (:return-type ftype))) - (exc/analyzer-error "Variable used as function name" {:symbol symbol - :expression e})))) + (if (symbol-function? symbol) + (let [_ (when (not= (count arguments) (count (:parameter-types ftype))) + (exc/analyzer-error "Function called with wrong number of arguments." + {:expected (count (:parameter-types ftype)) + :actual (count arguments)})) + cast-arg-to-param-type-f (fn [param-type arg] + (convert-to-exp (typecheck-exp arg ident->symbol) + param-type)) + converted-args (mapv cast-arg-to-param-type-f + (:parameter-types ftype) + arguments) + typed-fun-call-exp (p/function-call-exp-node identifier converted-args)] + (set-type typed-fun-call-exp (:return-type ftype))) + (exc/analyzer-error "Variable used as function name" {:symbol symbol + :expression e})))) (defmulti typecheck-statement "Dispatches based on type of statement. @@ -480,10 +482,10 @@ [program] (let [v (typecheck-program program) program (:program v) - m (dissoc (:ident->symbol v) :at-top-level) + m (dissoc (:ident->symbol v) :at-top-level)] ;_ (m/coerce s/Program program) ;_ (m/coerce s/SymbolMap m) - ] + {:program program :ident->symbol m})) |
