π»Add Features on Maryl
Here is all you need to know to implement a feature on Maryl
Adding New Syntax
To add new native elements to the language, you'll have to use Megaparsec. Go to src/Parsing/ParserAst.hs and follow these steps:
Parse a new symbol:
Create a function that parses your new symbol using Megaparsec's
Parser(e.g.: pPointer).Call your new function in one of the next steps.
Add a new type:
In the
MarylTypedata type, add your new type.To parse it, add it to the list of types in the
types'function. If the type is more complexe and needs extra informations, add its parsing function to thetypesfunction directly.Add the translation from
StringtoMarylTypein thegetTypefunction.Finally, don't forget to update the documentation so people know which type they can use!
Add a new statement:
Statements like
return,if, loops, should be added to thepTermfunction.Add the newly parsed statement as a new
Asttype in the structure.
Add a new assignment (
=):Just add your new assignment symbol in the
eqSymbolfunction.
Add a new operator:
Maryl parsing for operators is done with the built-in
makeExprParserof Megaparsec, so you just have to add your new operator to theoperatorTable.
Now that you've added your newly parsed value, you have to add it to the evaluation, in the src/Evalfolder.
Adding Built-in Functions
To add new built-in functions to Maryl, follow these steps:
Define your operator in
VirtualMachine/Interpreter.hs:
Register your operator in the
operatorslist:
Extending the Syntax
To add new syntax elements to the language:
Add a new instruction type in
VirtualMachine/Instructions.hs:
Create a constructor for your instruction:
Add a parser in
VirtualMachine/Parser.hs:
Add your parser to the
keyWordslist:
Implement the execution logic in
VirtualMachine/Interpreter.hs:
Integration with External Libraries
To integrate external libraries with Maryl:
Create a new operator that wraps your external function in
VirtualMachine/Interpreter.hsUse the
iofunction to lift IO operations into the VmState monad:
Register your external function as an operator following the steps in "Adding Built-in Functions"
Or, create a file ending in .mrland its code can be imported in your programs by simply typing:
Remember to:
Handle errors appropriately using
failoreitherSMaintain type safety by properly converting between Value and your external types
Document any new dependencies in the project's cabal file
Adding a New Operator (Evaluation stage)
To add a new operator, follow these steps:
Define the Operator's Functionality:
Implement the evaluation logic in
Eval.Ops.The function signature should match others, e.g.,
evalNewOp :: Memory -> Ast -> Ast -> Either String (Ast, Memory).
Register the Operator:
Add the operator to the
defaultRegistryinEvaluator.hs:
Specify Return Types:
Update
assocOpExpectationinEval.Opsto define the valid return types for the new operator:
Adding a New Operator (Translation stage)
To support a new operator:
Update
translateOpInst:Add the new operator and its corresponding VM instruction:
If the instruction doesn't exist in
VirtualMachine.Instructions, define it there first.
Update
isSingleOp:Ensure the operator is marked as a single operator if it doesn't represent a compound assignment:
Test the Operator:
Write test cases for the operator to verify correct translation and VM behavior.
Adding New AST Node (Evaluation Stage)
Define the Node:
Extend the
Asttype inParsing.ParserAstto include the new node.
Implement Evaluation Logic:
Add a case for the new node in
evalNode:
Update Supporting Functions:
If the new node affects structures like
evalAST,applyOp, or memory functions, update those as needed.
Adding New AST Node (Translation Stage)
To support a new AST node:
Extend the AST Definition:
Add the new node to the
Astdata type inParsing.ParserAst.
Implement Translation Logic:
Add a case for the new node in
translateAST:Generate appropriate instructions using the
VirtualMachine.Instructionsmodule.
Update Supporting Functions:
If the new node interacts with specific constructs (e.g., conditionals or loops), update the relevant translation functions like
translateIfortranslateLoop.
Adding New Maryl Types
Define the Type:
Extend the
MarylTypeenumeration inParsing.ParserAst.
Update Validation:
Update
isValidTypeandisSameTypeto include the new type.
Add Usage Logic:
Modify relevant sections like
evalDefinition,evalAssignType, orevalBinaryRetto handle the new type.
Last updated

