Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions code/drasil-gool/lib/Drasil/GOOL/InterfaceGOOL.hs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class (ValueSym r, OOTypeSym r) => OOValueSym r
class (VariableSym r, OOTypeSym r) => OOVariableSym r where
-- Bool: False for variable, True for constant. Required by the Python renderer.
staticVar' :: Bool -> Label -> VSType r -> SVariable r
-- We should probably have a way to make this a constant that can't have an L-Value
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, a redesign of L-Values would be good.

self :: SVariable r
classVar :: VSType r -> SVariable r -> SVariable r
extClassVar :: VSType r -> SVariable r -> SVariable r
Expand Down
4 changes: 4 additions & 0 deletions code/drasil-gool/lib/Drasil/GOOL/RendererClassesOO.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ class (BlockCommentSym r) => RenderFile r where

fileFromData :: FilePath -> IG.FSModule r -> IG.SFile r

-- This assumes a certain representation for Permanence
class PermElim r where
perm :: r (IG.Permanence r) -> Doc
binding :: r (IG.Permanence r) -> Binding

-- Why do we have these here on top of InterfaceCommon?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Search for the PRs that introduced them, I'm pretty sure there are comments there for why. There was a reason!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked for getFunc from here and getMethod from InterfaceGOOL.

getFunc was renamed and moved around a few times, the earliest being when it was renamed from get to getFunc in Created 'get' Value Function combination. Before then, it seems to appear from nowhere in Finally Tagless GOOL.

getMethod also seems to appear from nowhere in Finally Tagless GOOL.

I think the history is weird for that commit because it was merged from Brooks's fork. I'll have to go there and see if I can trace it back further when I have time.

class InternalGetSet r where
getFunc :: SVariable r -> VSFunction r
setFunc :: VSType r -> SVariable r -> SValue r -> VSFunction r
Expand All @@ -63,6 +65,7 @@ class (RenderMethod r, OOMethodTypeSym r) => OORenderMethod r where

destructor :: [IG.CSStateVar r] -> SMethod r

-- This assumes a certain representation for StateVar
class StateVarElim r where
stateVar :: r (IG.StateVar r) -> Doc

Expand All @@ -85,5 +88,6 @@ class RenderMod r where
modFromData :: String -> FS Doc -> IG.FSModule r
updateModuleDoc :: (Doc -> Doc) -> r (IG.Module r) -> r (IG.Module r)

-- This assumes a certain representation for Module
class ModuleElim r where
module' :: r (IG.Module r) -> Doc
11 changes: 10 additions & 1 deletion code/drasil-gool/lib/Drasil/Shared/InterfaceCommon.hs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ class TypeSym r where
funcType :: [VSType r] -> VSType r -> VSType r
void :: VSType r

-- We've established that getTypeString is a bad thing
-- getType might be required, but without global state should it be a class?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getType is used to do a little bit of introspection. There might be other ways to do that.

It's a class because we should always be able to do that, and implementation can be per-language.

class (TypeSym r) => TypeElim r where
getType :: r (Type r) -> CodeType
getTypeString :: r (Type r) -> String
Expand All @@ -108,6 +110,7 @@ class (TypeSym r) => VariableSym r where
extVar :: Library -> Label -> VSType r -> SVariable r
arrayElem :: Integer -> SVariable r -> SVariable r

-- Similar here - shouldn't we be handling this on a per-language basis?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

classes exactly let you do things per-language. Now, if you mean that each language might want to vary this signature, that's different!

class (VariableSym r) => VariableElim r where
variableName :: r (Variable r) -> String
variableType :: r (Variable r) -> r (Type r)
Expand All @@ -120,6 +123,7 @@ listOf = listVar

type SValue a = VS (a (Value a))

-- Similar here - is this the best way to get the type of a value?
class (TypeSym r) => ValueSym r where
type Value r
valueType :: r (Value r) -> r (Type r)
Expand Down Expand Up @@ -256,6 +260,8 @@ libFuncApp l n t vs = libFuncAppMixedArgs l n t vs []
exists :: (ValueExpression r) => SValue r -> SValue r
exists = notNull

-- These all return SValue, but shouldn't they return MSStatement?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're really hoping that all languages have List as values. Except that there might not be "lists" per se, just mis-named, they might be arrays (since indexOf is an evil thing to do to a list).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I was specifically referring to listAdd, listAppend, listSet. These usually mutate the list and return void.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think we should have two sets of "list interfaces", one that assumes pure, and one that assumes imperative.

-- Also, they have the issue of not distinguishing Values and L-Values (See below)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely.

class (ValueSym r) => List r where
-- | Does any necessary conversions from GOOL's zero-indexed assumptions to
-- the target language's assumptions
Expand All @@ -282,6 +288,7 @@ class (ValueSym r) => List r where
-- Arguments are: List, Value
indexOf :: SValue r -> SValue r -> SValue r

-- Similar to List, shouldn't most of these be statements?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with list, we're hoping not. But that might be a mistake.

class (ValueSym r) => Set r where
-- | Checks membership
-- Arguments are: Set, Value
Expand Down Expand Up @@ -377,6 +384,8 @@ assignToListIndex :: (StatementSym r, VariableValue r, List r) => SVariable r
-> SValue r -> SValue r -> MSStatement r
assignToListIndex lst index v = valStmt $ listSet (valueOf lst) index v

-- As Reed mentioned, these have a lack of distinction between values/variables
-- and L-Values
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. But we need a reason to make that distinction. For L-Values, I think that's clear. Between values and variables, does our code actually need to know that? [The answer could be a resounding 'yes'; the point is to be explicit as to why.]

class (VariableSym r, StatementSym r, ScopeSym r) => DeclStatement r where
varDec :: SVariable r -> r (Scope r) -> MSStatement r
varDecDef :: SVariable r -> r (Scope r) -> SValue r -> MSStatement r
Expand All @@ -392,7 +401,7 @@ class (VariableSym r, StatementSym r, ScopeSym r) => DeclStatement r where
funcDecDef :: SVariable r -> r (Scope r) -> [SVariable r] -> MSBody r
-> MSStatement r


-- More places that could benefit from L-Values
class (VariableSym r, StatementSym r) => IOStatement r where
print :: SValue r -> MSStatement r
printLn :: SValue r -> MSStatement r
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ objVar o' v' = do
(variableType v) (R.objVar (RC.variable o) (RC.variable v))
objVar' (variableBind v)

-- This seems a bit sketchy - unwrapping everything to Doc, mixing it up, then wrapping it back to Variable
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is supposed to create something that points to an array element, and then will be used as if it were a variable.

This is likely only used on the LHS, so that a redesign of L-Values might get rid of this.

arrayElem :: (OORenderSym r) => SValue r -> SVariable r -> SVariable r
arrayElem i' v' = do
i <- IC.intToIndex i'
Expand Down
24 changes: 21 additions & 3 deletions code/drasil-gool/lib/Drasil/Shared/RendererClassesCommon.hs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class (AssignStatement r, DeclStatement r, IOStatement r,

-- Common Typeclasses --

-- Couldn't this just be in InterfaceCommon?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most likely.

class ImportSym r where
type Import r
-- For importing an external library
Expand All @@ -69,18 +70,23 @@ class BodyElim r where
class RenderBlock r where
multiBlock :: [MSBlock r] -> MSBlock r

-- This assumes that the renderers encode Body as Doc
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, this assumes that the only thing to ever be done with a Block will be to render it. This might not be a good assumption.

class BlockElim r where
block :: r (Block r) -> Doc

-- This relates to TypeData, which keeps ADT, String, and Doc representations of a type for _reasons_
class RenderType r where
multiType :: [VSType r] -> VSType r
typeFromData :: CodeType -> String -> Doc -> VSType r

-- This is coupled to TypeData
class InternalTypeElim r where
type' :: r (Type r) -> Doc

type VSUnOp a = VS (a (UnaryOp a))

-- Why do we have these, when we also have NumericExpression in InterfaceCommon?
-- It looks like the implementations for NumericExpression link here, but why?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't remember. Sleuth through the PRs that introduce this?

class UnaryOpSym r where
type UnaryOp r
notOp :: VSUnOp r
Expand Down Expand Up @@ -124,12 +130,16 @@ class OpElim r where
uOpPrec :: r (UnaryOp r) -> Int
bOpPrec :: r (BinaryOp r) -> Int

-- These assume we represent Scope with ScopeData
class ScopeElim r where
scopeData :: r (Scope r) -> ScopeData


-- What exactly is this, since it adds a bunch of extra required data?
class RenderVariable r where
varFromData :: Binding -> String -> VSType r -> Doc -> SVariable r


-- This assumes variables are represented in a certain way, and
-- its existence seems a bit sketchy
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is likely used for doing a bit of introspection. Might not be needed if the information is available by other means.

class InternalVarElim r where
variableBind :: r (Variable r) -> Binding
variable :: r (Variable r) -> Doc
Expand Down Expand Up @@ -157,6 +167,7 @@ class ValueElim r where
valueInt :: r (Value r) -> Maybe Integer
value :: r (Value r) -> Doc

-- Again, wh are we recreating all these list functions?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is likely a single language that needs a "middle layer" to intercept these, tweak, and pass on.

class InternalListFunc r where
-- | List
listSizeFunc :: SValue r -> VSFunction r
Expand All @@ -172,10 +183,12 @@ class InternalListFunc r where
class RenderFunction r where
funcFromData :: Doc -> VSType r -> VSFunction r

-- Assumes a certain representation for functions
class FunctionElim r where
functionType :: r (Function r) -> r (Type r)
function :: r (Function r) -> Doc

-- Shouldn't this be in InterfaceCommon?
class InternalAssignStmt r where
multiAssign :: [SVariable r] -> [SValue r] -> MSStatement r

Expand All @@ -198,13 +211,16 @@ class StatementElim r where

class RenderVisibility r where
visibilityFromData :: VisibilityTag -> Doc -> r (Visibility r)


-- This assumes a certain representation of visibility
class VisibilityElim r where
visibility :: r (Visibility r) -> Doc

-- Why do we need a Doc here?
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only the instance can tell!

class RenderParam r where
paramFromData :: SVariable r -> Doc -> MSParameter r

-- This assumes a certain representation for Parameter
class ParamElim r where
parameterName :: r (Parameter r) -> Label
parameterType :: r (Parameter r) -> r (Type r)
Expand All @@ -216,6 +232,7 @@ class BlockCommentSym r where
-- | Converts a list of strings into a block comment
docComment :: State a [String] -> State a (r (BlockComment r))

-- This assumes a certain representation for BlockComment
class BlockCommentElim r where
blockComment' :: r (BlockComment r) -> Doc

Expand All @@ -230,5 +247,6 @@ class (MethodTypeSym r, BlockCommentSym r) => RenderMethod r where
commentedFunc :: MS (r (BlockComment r)) -> SMethod r -> SMethod r
mthdFromData :: VisibilityTag -> Doc -> SMethod r

-- This assumes a certain representation for Method
class MethodElim r where
method :: r (Method r) -> Doc