Skip to content

Commit

Permalink
Merge pull request #44 from lyncmi07/34_source_code_positions
Browse files Browse the repository at this point in the history
34 source code positions
Closes 34
  • Loading branch information
lyncmi07 authored Oct 24, 2019
2 parents a10a8e6 + 9a6e8d6 commit 9b61370
Show file tree
Hide file tree
Showing 44 changed files with 1,184 additions and 730 deletions.
45 changes: 27 additions & 18 deletions app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import Com.NoSyn.Parser.ConcreteSyntaxConverter
import Com.NoSyn.Environment.ProgramEnvironment
import Com.NoSyn.Environment.FunctionEnvironment
import Com.NoSyn.Error.CompilerStatus
import Com.NoSyn.Error.SourcePosition hiding (getContents)
import Com.NoSyn.Error.SourcePositionTraits
import qualified Com.NoSyn.Error.SourcePosition as SourcePosition (getContents)
import Com.NoSyn.Ast.Traits.IfElementGeneratable
import Com.NoSyn.Ast.Traits.TargetCodeGeneratable
import Com.NoSyn.Ast.Traits.Listable as Listable
Expand All @@ -23,32 +26,38 @@ import Com.NoSyn.Ast.If.PreProgram as IfPreProgram
import Com.NoSyn.Ast.Ifm1.ImportStatement as Ifm1ImportStatement
import Com.NoSyn.Ast.If.ImportStatement
import Com.NoSyn.Ast.If.IfElement
import Com.NoSyn.Ast.If.Block
import Data.Foldable

main = do
args <- getArgs
(headerText, programText) <- getContents >>= return.splitInputs
(headerText, programText) <- Prelude.getContents >>= return.splitInputs
(_, cst) <- convertToIO $ failOnNonFatalErrors programText (parse programText 0 1 [])
(_, ifm1Ast@(Ifm1PreProgram.PreProgram importStatments _)) <- convertToIO $ convertProgram cst
(_, ifAst) <- convertToIO $ generateIfElement defaultProgramEnvironment ifm1Ast
if args == [] then compileProgram headerText ifAst ifm1Ast
(_, positionedIfm1Ast) <- convertToIOWithSourcePositions programText $
let positionedIfAstResult = runCompilerStatusT $ convertProgram cst in do
ifm1Ast <- SourcePosition.getContents positionedIfAstResult
return $ changeContents positionedIfAstResult ifm1Ast
(_, positionedIfAst) <- convertToIOWithSourcePositions programText $ generateIfElement defaultProgramEnvironment positionedIfm1Ast
if args == [] then compileProgram programText headerText positionedIfAst positionedIfm1Ast
else let (x:_) = args in
if x == "--headers" then createHeaders ifAst
if x == "--headers" then createHeaders positionedIfAst
else putStrLn $ "Invalid argument: " ++ x

compileProgram headerText initialIfAst@(IfPreProgram (IfPreProgram.PreProgram allImports _)) ifm1Ast = do
(_, initialProgramEnvironment) <- convertToIO $ programEnvironmentEvaluateIfElement initialIfAst
-- Now that the program environment has been populated the ifAst is generated again to correct any missing function calls from expressions
selectedImports <- return $ filteredHeaders headerText (Listable.toList allImports)
(_, programEnvironmentWithImports) <- convertToIO $ addImportedFunctionsToEnvironment selectedImports initialProgramEnvironment
(_, ifAst) <- convertToIO $ generateIfElement programEnvironmentWithImports ifm1Ast
(dependencies, targetCode) <- convertToIO $ generateD programEnvironmentWithImports ifAst
putStrLn (concat $ intersperse "\n" dependencies)
putStrLn "%%SOURCE%%"
putStrLn targetCode
compileProgram sourceCode headerText spInitialIfAst spIfm1Ast = case SourcePosition.getContents spInitialIfAst of
IfPreProgram spcIfPreProgram -> case SourcePosition.getContents spcIfPreProgram of
IfPreProgram.PreProgram allImports _ -> do
(_, initialProgramEnvironment) <- convertToIOWithSourcePositions sourceCode $ programEnvironmentEvaluateIfElement (SourcePosition.getContents spInitialIfAst)
-- Now that the program environment has been populated the ifAst is generated again to correct any missing function calls from expressions
selectedImports <- return $ filteredHeaders headerText (Prelude.map SourcePosition.getContents $ toSourcePositionedList $ SourcePosition.getContents allImports)
(_, programEnvironmentWithImports) <- convertToIOWithSourcePositions sourceCode $ addImportedFunctionsToEnvironment selectedImports initialProgramEnvironment
(_, ifAst) <- convertToIOWithSourcePositions sourceCode $ generateIfElement programEnvironmentWithImports spIfm1Ast
(dependencies, targetCode) <- convertToIOWithSourcePositions sourceCode $ generateD programEnvironmentWithImports ifAst
putStrLn (concat $ intersperse "\n" dependencies)
putStrLn "%%SOURCE%%"
putStrLn targetCode

createHeaders ifAst = do
(_, functionEnvironment) <- convertToIO $ functionEnvironmentEvaluateIfElement ifAst
(_, functionEnvironment) <- convertToIO $ functionEnvironmentEvaluateIfElement $ SourcePosition.getContents ifAst
putStrLn $ serializeFunctionEnvironment functionEnvironment

splitInputs standardInput =
Expand Down Expand Up @@ -82,5 +91,5 @@ importedNSModulesList importStatements =
where
nsImportPredicate (NativeImport _) = False
nsImportPredicate (NSImport _) = True
importNameProvider (NativeImport a) = concat $ intersperse "." a
importNameProvider (NSImport a) = concat $ intersperse "." a
importNameProvider (NativeImport a) = concat $ intersperse "." (Prelude.map SourcePosition.getContents a)
importNameProvider (NSImport a) = concat $ intersperse "." (Prelude.map SourcePosition.getContents a)
1 change: 1 addition & 0 deletions package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ library:
- text-latin1
- split
- set-theory
- transformers

executables:
no-syn-exe:
Expand Down
2 changes: 2 additions & 0 deletions run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ stack install

for i in $(find ./test/*.ns)
do
echo "Running test $i"
if cat $i | no-syn-exe ; then
echo "$?"
else
Expand All @@ -14,6 +15,7 @@ done

for i in $(find ./test/*.ns.fail)
do
echo "Running test $i"
if cat $i | no-syn-exe ; then
echo "The test $i should have failed but did not"
exit 1
Expand Down
19 changes: 11 additions & 8 deletions src/Com/NoSyn/Ast/If/AliasDefinition.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
module Com.NoSyn.Ast.If.AliasDefinition where

import Prelude hiding (getContents)
import Com.NoSyn.Ast.Traits.TargetCodeGeneratable
import Com.NoSyn.Ast.Traits.EnvironmentUpdater
import Com.NoSyn.Environment.ProgramEnvironment
import Com.NoSyn.Data.Types
import Com.NoSyn.Error.CompilerStatus
import Com.NoSyn.Error.SourcePosition
import Data.Map.Ordered

data AliasDefinition =
Expand All @@ -13,13 +15,14 @@ data AliasDefinition =
deriving Show

instance TargetCodeGeneratable AliasDefinition where
generateD _ (ADNative _ _) = return "";
generateD _ (ADNoSyn _ _) = return "";
generateD _ spAliasDef = case getContents spAliasDef of
ADNative _ _ -> return ""
ADNoSyn _ _ -> return ""

instance EnvironmentUpdater AliasDefinition where
updateEnvironment programEnvironment@(PE { aliases = aliasEnvironment }) a@(ADNative _ _) =
Error "Native aliases have not been implemented yet" (show a)
updateEnvironment programEnvironment@(PE { aliases = aliasEnvironment }) (ADNoSyn aliasName aliasType) = do
_ <- lookupDType aliasType aliasEnvironment
let updatedAliasEnvironment = (aliasName, aliasType) |< aliasEnvironment in
return (programEnvironment { aliases = updatedAliasEnvironment })
updateEnvironment programEnvironment@(PE { aliases = aliasEnvironment }) spAliasDef = case getContents spAliasDef of
ADNative _ _ -> PositionedError (getSourcePosition spAliasDef) "Native aliases have not been implemented yet" (show $ getContents spAliasDef)
ADNoSyn aliasName aliasType -> do
_ <- lookupDType aliasType aliasEnvironment
let updatedAliasEnvironment = (aliasName, aliasType) |< aliasEnvironment in
return (programEnvironment { aliases = updatedAliasEnvironment })
56 changes: 33 additions & 23 deletions src/Com/NoSyn/Ast/If/Block.hs
Original file line number Diff line number Diff line change
@@ -1,43 +1,53 @@
module Com.NoSyn.Ast.If.Block where

import Prelude hiding (getContents)
import Com.NoSyn.Ast.Traits.TargetCodeGeneratable
import Com.NoSyn.Ast.Traits.Listable
import Com.NoSyn.Ast.Traits.EnvironmentUpdater
import Com.NoSyn.Ast.Traits.Blockable
import Data.List
import Data.Set.SetTheory
import Control.Monad
import Com.NoSyn.Error.CompilerStatus
import Com.NoSyn.Error.SourcePosition
import Com.NoSyn.Error.SourcePositionTraits
import Com.NoSyn.Environment.ProgramEnvironment
import Com.HigherOrderFunctions

class (EnvironmentUpdater m) => Blockable m where
blockSeparator :: m->String

data Block a =
StandardBlock [a]
| SequentialBlock [a]
StandardBlock [SourcePosition a]
| SequentialBlock [SourcePosition a]
deriving Show

instance (EnvironmentUpdater a) => EnvironmentUpdater (Block a) where
updateEnvironment programEnvironment (StandardBlock m) = do
updatedProgramEnvironments <- sequence $ map (updateEnvironment programEnvironment) m
let differenceProgramEnvironments = map (\x -> difference x programEnvironment) updatedProgramEnvironments in
foldM (\x y -> concatenate (Error "Cannot override program environment with new definitions" (show (x, y))) x y) programEnvironment differenceProgramEnvironments
updateEnvironment programEnvironment (SequentialBlock m) =
foldM updateEnvironment programEnvironment m
updateEnvironment programEnvironment spBlock = case getContents spBlock of
StandardBlock m -> do
updatedProgramEnvironments <- sequence $ map (updateEnvironment programEnvironment) m
let differenceProgramEnvironments = map (\x -> difference x programEnvironment) updatedProgramEnvironments in
foldM
(\x y -> concatenate (PositionedError (getSourcePosition spBlock) "Cannot override program environment with new definitions" (show (x, y))) x y)
programEnvironment
differenceProgramEnvironments
SequentialBlock m ->
foldM updateEnvironment programEnvironment m

instance (EnvironmentUpdater a, TargetCodeGeneratable a, Blockable a) => TargetCodeGeneratable (Block a) where
generateD programEnvironment (StandardBlock a) = do
generatedElements <- sequence $ map (generateD programEnvironment) a
return $
concat $
intersperse (blockSeparator (head a)) generatedElements
generateD programEnvironment (SequentialBlock a) = do
generatedElements <- environmentUpdatingMapMonad updateEnvironment generateD programEnvironment a
return $
concat $
intersperse (blockSeparator (head a)) generatedElements
generateD programEnvironment spBlock = case getContents spBlock of
StandardBlock a -> do
generatedElements <- sequence $ map (generateD programEnvironment) a
return $ concat $ intersperse (blockSeparator (head a)) generatedElements
SequentialBlock a -> do
generatedElements <- environmentUpdatingMapMonad updateEnvironment generateD programEnvironment $ a
return $ concat $ intersperse (blockSeparator (head a)) generatedElements

instance Listable Block where
toList (StandardBlock a) = a
toList (SequentialBlock a) = a
toList (StandardBlock a) = getContents $ sequence a
toList (SequentialBlock a) = getContents $ sequence a

toSourcePositionedList :: Block a -> [SourcePosition a]
toSourcePositionedList (StandardBlock l) = l
toSourcePositionedList (SequentialBlock l) = l

instance Functor Block where
fmap f (StandardBlock a) = StandardBlock $ map (fmap f) a
fmap f (SequentialBlock a) = SequentialBlock $ map (fmap f) a
13 changes: 7 additions & 6 deletions src/Com/NoSyn/Ast/If/Constant.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
module Com.NoSyn.Ast.If.Constant where

import Prelude hiding (getContents)
import Com.NoSyn.Ast.Traits.Typeable
import Com.NoSyn.Ast.Traits.TargetCodeGeneratable
import Com.NoSyn.Environment.ProgramEnvironment
import Com.NoSyn.Error.SourcePosition

data Constant =
CInt Int
Expand All @@ -12,12 +14,11 @@ data Constant =
deriving Show

instance TargetCodeGeneratable Constant where
generateD _ (CInt i) = return (show i)
generateD _ (CDouble d) = return (show d)
generateD _ (CChar c) = return (show c)
generateD _ (CString s) = return (show s)


generateD _ spConstant = case getContents spConstant of
CInt i -> return (show i)
CDouble d -> return (show d)
CChar c -> return (show c)
CString s -> return (show s)

instance Typeable Constant where
getTypeNoCheck (CInt _) = "Int"
Expand Down
Loading

0 comments on commit 9b61370

Please sign in to comment.