<commit_before>{-# LANGUAGE FlexibleInstances #-}

module Oodle.TypeChecker (typeChecker) where

import Oodle.Error
import Oodle.ParseTree
import Oodle.SymbolTable (
  SymbolTable
  , resolveScope
  , getMethodDecl
  , getNamedDecl
  , getParameterTypes
  , getVariables
  , type'
  , unbuildArray
  , symbol
  , Scope)
import qualified Oodle.SymbolTable (getType)
import Oodle.SymbolTableBuilder (getSymbolTable)
import Oodle.TreeWalker
import Oodle.Token (Token, fakeToken)

-- Check Types
--

yay :: Error Type
yay = return typeNull

typeChecker :: SymbolTable -> Start -> Error Type
typeChecker st = walk (st, (head st), (head st), False)
instance Walkable (Error Type) where
  reduce types = do
    t <- sequence types
    case t of
      []  -> yay
      _   -> return (head t)

  doClass     _ _ _ _ _ _ = yay
  doMethod  _ _ _ _ _ _ _ = yay
  doArgument      _ _ _ _ = yay
  doArgumentArr _ _ _ _ _ = yay
  doVariable _ tk name t (_, exprT') = do
    exprT <- exprT'
    if (t == exprT) || (t == typeNull) || (exprT == TypeNoop) then
      yay
    else
      fail (msgWithToken tk (wrongTypeMsg t exprT) name)

  doAssignStmtArr scope tk name (arrayScope, arrayScope') (_, exprT') = do
    t <- getVarType scope (IdArray name arrayScope)
    arrayScope'' <- arrayScope'
    exprT <- exprT'
    if arrayScope'' == TypeInt then
      if t == exprT then
        yay
      else fail (msgWithToken' tk $ wrongTypeMsg t exprT)
    else fail (msgWithToken' tk $ wrongTypeMsg TypeInt arrayScope'')

  doAssignStmt scope tk name (_, expr) = do
    t <- getVarType scope (Id name)
    exprT <- expr
    let failMe = fail (msgWithToken' tk (wrongTypeMsg t exprT))
<commit_msg>Don't allow variables of any type.<commit_after>{-# LANGUAGE FlexibleInstances #-}

module Oodle.TypeChecker (typeChecker, typeOfExpression) where

import Oodle.Error
import Oodle.ParseTree
import Oodle.SymbolTable (
  SymbolTable
  , findSymbol
  , resolveScope
  , getMethodDecl
  , getNamedDecl
  , getParameterTypes
  , getVariables
  , type'
  , unbuildArray
  , symbol
  , Scope)
import qualified Oodle.SymbolTable (getType)
import Oodle.SymbolTableBuilder (getSymbolTable)
import Oodle.TreeWalker
import Oodle.Token (Token, fakeToken)

-- Check Types
--

yay :: Error Type
yay = return typeNull

typeChecker :: SymbolTable -> Start -> Error Type
typeChecker st = walk (st, (head st), (head st), False)
instance Walkable (Error Type) where
  reduce types = do
    t <- sequence types
    case t of
      []  -> yay
      _   -> return (head t)

  doClass     _ _ _ _ _ _ = yay
  doMethod  _ _ _ _ _ _ _ = yay
  doArgument      _ _ _ _ = yay
  doArgumentArr _ _ _ _ _ = yay
  doVariable (st, _, _, _) tk name t (_, exprT') = do
    exprT <- exprT'
    tExists <- tExists'
    if tExists && (t == exprT) || (exprT == typeNull) || (exprT == TypeNoop) then
      yay
    else
      fail (msgWithToken tk (wrongTypeMsg t exprT) name)
    where tExists' = case t of
                      (TypeId (Id typeName)) ->
                        case findSymbol st (typeName, tk) of
                          Ok _ -> return True
                          Failed _ ->
                            fail $ msgWithToken tk "undefined class" typeName
                      TypeNoop        -> return False
                      _               -> return True

  doAssignStmtArr scope tk name (arrayScope, arrayScope') (_, exprT') = do
    t <- getVarType scope (IdArray name arrayScope)
    arrayScope'' <- arrayScope'
    exprT <- exprT'
    if arrayScope'' == TypeInt then
      if t == exprT then
        yay
      else fail (msgWithToken' tk $ wrongTypeMsg t exprT)
    else fail (msgWithToken' tk $ wrongTypeMsg TypeInt arrayScope'')

  doAssignStmt scope tk name (_, expr) = do
    t <- getVarType scope (Id name)
    exprT <- expr
    let failMe = fail (msgWithToken' tk (wrongTypeMsg t exprT))

{'fraction_non_alphanumeric': 0.09170984455958549, 'fraction_numerical': 0.0, 'mean_word_length': 2.4783783783783786, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1637025', 'n_tokens_mistral': 1268, 'n_tokens_neox': 1246, 'n_words': 382}