Skip to content

Commit

Permalink
resolve conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
bristermitten committed Mar 27, 2024
1 parent 068a992 commit 52c5f02
Showing 1 changed file with 38 additions and 94 deletions.
132 changes: 38 additions & 94 deletions templatespiler-converter/src/Templatespiler/IR/Imperative.hs
Original file line number Diff line number Diff line change
@@ -1,105 +1,49 @@
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE OverloadedStrings #-}

-- | A lightweight imperative language that is used as an IR
{- | Imperative flavoured IR for templatespiler.
While there's different details, all imperative languages are gonna largely have the same structure:
- read how many inputs there are
- loop over said variable and read more things
- insert to an array if necessary
- repeat if necessary
- print something (not our concern)
-}
module Templatespiler.IR.Imperative where

import Templatespiler.IR.Common
import Templatespiler.IR.Common (SingleLineString)
import Prelude hiding (Type)

import Prettyprinter
newtype VarName = VarName Text

import Prelude hiding (group)
data Terminal
= StringTerminal
| IntegerTerminal
| FloatTerminal

withSuffix :: VarName -> Text -> VarName
withSuffix (VarName (n :| ns)) suffix = VarName (n :| (ns <> [suffix]))

type Program = [Statement]
data Type
= TerminalType Terminal
| -- | An "array", which may be a list or a fixed size array depending on target language. The length must be known at compile time.
ArrayType
VarName
Type

data Statement
= -- | Variable declaration. This may be a C-style declaration (@int x@) or an assignment (@x = 0@) depending on the target language.
Decl
= -- | Variable declaration, for statically typed languages or initialization for scope
DeclareVar VarName Type
| -- | Read one or more variables from stdin, separated by spaces. Having this as a single statement means more idiomatic usage of things like scanf in C.
ReadVars
SingleLineString
-- ^ Separator string
(NonEmpty (VarName, Type))
-- ^ Variable names and types
| LoopNTimes
VarName
-- ^ The variable name
VarType
-- ^ The type
| Assign VarName VarType Expr
| -- | Read 1 line of input, split it by some separator, and then read into separate variables
MultiReadAssign
Text
-- ^ Separator
(NonEmpty (VarName, ReadType))
| For
VarName -- variable name
Expr -- start
Expr -- end
[Statement] -- body
| AppendToArray
[Statement]
| -- | Array assignment
ArrayAssign
VarName
-- ^ array name
Expr
-- ^ index
Expr
-- ^ value
deriving stock (Show)

data VarType
= IntType
| FloatType
| StringType
| ArrayType Expr VarType
| DynamicArrayType VarType
| TupleOrStructType (Maybe VarName) (NonEmpty VarType)
| UnknownType
deriving stock (Show)

data Expr
= ConstInt Int
| Var VarName
| ReadAtom ReadType
| TupleOrStruct (Maybe VarName) (NonEmpty Expr)
deriving stock (Show)

data ReadType
= ReadInt
| ReadFloat
| ReadString
deriving stock (Show, Eq, Ord)

prettyExpr :: Expr -> Doc nn
prettyExpr (ConstInt i) = pretty i
prettyExpr (Var vn) = pretty vn
prettyExpr (ReadAtom rt) = "read" <+> pretty rt
prettyExpr (TupleOrStruct n es) = pretty n <> tupled (fmap prettyExpr (toList es))

prettyVarType :: VarType -> Doc ann
prettyVarType IntType = "Int"
prettyVarType FloatType = "Float"
prettyVarType StringType = "String"
prettyVarType (ArrayType e t) = prettyVarType t <> brackets (prettyExpr e)
prettyVarType (DynamicArrayType t) = prettyVarType t <> "*"
prettyVarType (TupleOrStructType n ts) = pretty n <> tupled (fmap prettyVarType (toList ts))
prettyVarType UnknownType = "UnknownType"

instance Pretty ReadType where
pretty ReadInt = "@Int"
pretty ReadFloat = "@Float"
pretty ReadString = "@String"

instance Pretty Statement where
pretty (Decl vn vt) = prettyVarType vt <+> pretty vn
pretty (Assign vn vt e) = pretty vn <+> "=" <+> prettyExpr e
pretty (MultiReadAssign sep vs) = "read" <+> dquotes (pretty sep) <+> hsep (fmap (\(vn, rt) -> pretty vn <> pretty rt) (toList vs))
pretty (For vn start end body) =
group $
vsep
[ nest 2 $
vsep
[ "for" <+> parens (pretty vn <+> "in" <+> prettyExpr start <> ".." <> prettyExpr end) <+> "{"
, vsep $ toList $ fmap pretty body
]
, "}"
]
pretty (AppendToArray vn idx val) = pretty vn <> brackets (prettyExpr idx) <+> "=" <+> prettyExpr val

prettyProgram :: Program -> Doc ann
prettyProgram = vsep . fmap pretty
-- ^ Array variable name
VarName
-- ^ Index variable name
VarName
-- ^ Value variable name

0 comments on commit 52c5f02

Please sign in to comment.