moldo 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
moldo-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Mutiibwa Grace Peter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
moldo-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,107 @@
1
+ Metadata-Version: 2.4
2
+ Name: moldo
3
+ Version: 0.1.0
4
+ Summary: A visual programming language that compiles to Python
5
+ Home-page: https://github.com/mutiibwa/moldo
6
+ Author: Mutiibwa Grace Peter
7
+ Author-email: mutiibwa.grace@example.com
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Education
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: Topic :: Software Development :: Compilers
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: antlr4-python3-runtime>=4.13.1
22
+ Dynamic: author
23
+ Dynamic: author-email
24
+ Dynamic: classifier
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: license-file
29
+ Dynamic: requires-dist
30
+ Dynamic: requires-python
31
+ Dynamic: summary
32
+
33
+ # Moldo - Visual Programming Language
34
+
35
+ Moldo is a visual programming language that compiles to Python. It provides a block-based interface for creating programs while maintaining the power and flexibility of Python.
36
+
37
+ ## Features
38
+
39
+ - Visual block-based programming interface
40
+ - Compiles to Python code
41
+ - Supports basic programming constructs (variables, input, loops)
42
+ - Can import and use Python functions through decorators
43
+ - Real-time code execution
44
+ - File saving and loading
45
+
46
+ ## Installation
47
+
48
+ 1. Clone the repository:
49
+ ```bash
50
+ git clone https://github.com/yourusername/moldo.git
51
+ cd moldo
52
+ ```
53
+
54
+ 2. Install dependencies:
55
+ ```bash
56
+ pip install -r requirements.txt
57
+ ```
58
+
59
+ 3. Generate ANTLR files:
60
+ ```bash
61
+ antlr4 -Dlanguage=Python3 moldo/compiler/grammar.py
62
+ ```
63
+
64
+ ## Usage
65
+
66
+ ### Starting the API Server
67
+
68
+ ```bash
69
+ uvicorn moldo.api.server:app --reload
70
+ ```
71
+
72
+ ### Using the Visual Editor
73
+
74
+ 1. Open the visual editor in your browser
75
+ 2. Drag and drop blocks to create your program
76
+ 3. Click "Run" to execute the code
77
+ 4. Use "Save" to save your program as a Moldo file
78
+
79
+ ### Python Integration
80
+
81
+ To make Python functions available in Moldo, use the `@moldo_function` decorator:
82
+
83
+ ```python
84
+ from moldo.decorators import moldo_function
85
+
86
+ @moldo_function(reference_name="add_numbers")
87
+ def add(a: int, b: int) -> int:
88
+ return a + b
89
+ ```
90
+
91
+ ## Project Structure
92
+
93
+ - `moldo/compiler/` - Contains the Moldo language compiler
94
+ - `grammar.py` - ANTLR grammar definition
95
+ - `parser.py` - Parser implementation
96
+ - `generator.py` - Python code generator
97
+ - `moldo/editor/` - Visual editor implementation
98
+ - `moldo/api/` - REST API server
99
+ - `moldo/decorators.py` - Python integration decorators
100
+
101
+ ## Contributing
102
+
103
+ Contributions are welcome! Please feel free to submit a Pull Request.
104
+
105
+ ## License
106
+
107
+ This project is licensed under the MIT License - see the LICENSE file for details.
moldo-0.1.0/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # Moldo - Visual Programming Language
2
+
3
+ Moldo is a visual programming language that compiles to Python. It provides a block-based interface for creating programs while maintaining the power and flexibility of Python.
4
+
5
+ ## Features
6
+
7
+ - Visual block-based programming interface
8
+ - Compiles to Python code
9
+ - Supports basic programming constructs (variables, input, loops)
10
+ - Can import and use Python functions through decorators
11
+ - Real-time code execution
12
+ - File saving and loading
13
+
14
+ ## Installation
15
+
16
+ 1. Clone the repository:
17
+ ```bash
18
+ git clone https://github.com/yourusername/moldo.git
19
+ cd moldo
20
+ ```
21
+
22
+ 2. Install dependencies:
23
+ ```bash
24
+ pip install -r requirements.txt
25
+ ```
26
+
27
+ 3. Generate ANTLR files:
28
+ ```bash
29
+ antlr4 -Dlanguage=Python3 moldo/compiler/grammar.py
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ### Starting the API Server
35
+
36
+ ```bash
37
+ uvicorn moldo.api.server:app --reload
38
+ ```
39
+
40
+ ### Using the Visual Editor
41
+
42
+ 1. Open the visual editor in your browser
43
+ 2. Drag and drop blocks to create your program
44
+ 3. Click "Run" to execute the code
45
+ 4. Use "Save" to save your program as a Moldo file
46
+
47
+ ### Python Integration
48
+
49
+ To make Python functions available in Moldo, use the `@moldo_function` decorator:
50
+
51
+ ```python
52
+ from moldo.decorators import moldo_function
53
+
54
+ @moldo_function(reference_name="add_numbers")
55
+ def add(a: int, b: int) -> int:
56
+ return a + b
57
+ ```
58
+
59
+ ## Project Structure
60
+
61
+ - `moldo/compiler/` - Contains the Moldo language compiler
62
+ - `grammar.py` - ANTLR grammar definition
63
+ - `parser.py` - Parser implementation
64
+ - `generator.py` - Python code generator
65
+ - `moldo/editor/` - Visual editor implementation
66
+ - `moldo/api/` - REST API server
67
+ - `moldo/decorators.py` - Python integration decorators
68
+
69
+ ## Contributing
70
+
71
+ Contributions are welcome! Please feel free to submit a Pull Request.
72
+
73
+ ## License
74
+
75
+ This project is licensed under the MIT License - see the LICENSE file for details.
File without changes
File without changes
@@ -0,0 +1,99 @@
1
+ from fastapi import FastAPI, HTTPException
2
+ from pydantic import BaseModel
3
+ from typing import Optional, Dict, Any, List
4
+ from ..compiler.parser import MoldoParser
5
+ from ..decorators import MoldoFunction
6
+
7
+ app = FastAPI(title="Moldo API")
8
+ parser = MoldoParser()
9
+
10
+ class MoldoCode(BaseModel):
11
+ code: str
12
+ python_modules: Optional[Dict[str, str]] = None
13
+
14
+ class ExecutionResult(BaseModel):
15
+ output: str
16
+ error: Optional[str] = None
17
+
18
+ @app.post("/compile")
19
+ async def compile_code(moldo_code: MoldoCode) -> Dict[str, str]:
20
+ """
21
+ Compile Moldo code to Python.
22
+
23
+ Args:
24
+ moldo_code: The Moldo code to compile
25
+
26
+ Returns:
27
+ Dictionary containing the generated Python code
28
+ """
29
+ try:
30
+ # Import any Python modules if provided
31
+ if moldo_code.python_modules:
32
+ for name, path in moldo_code.python_modules.items():
33
+ parser.import_python_module(path)
34
+
35
+ # Compile the Moldo code
36
+ python_code = parser.parse(moldo_code.code)
37
+ return {"python_code": python_code}
38
+ except Exception as e:
39
+ raise HTTPException(status_code=400, detail=str(e))
40
+
41
+ @app.post("/execute")
42
+ async def execute_code(moldo_code: MoldoCode) -> ExecutionResult:
43
+ """
44
+ Execute Moldo code and return the result.
45
+
46
+ Args:
47
+ moldo_code: The Moldo code to execute
48
+
49
+ Returns:
50
+ Execution result containing output and any errors
51
+ """
52
+ try:
53
+ # Import any Python modules if provided
54
+ if moldo_code.python_modules:
55
+ for name, path in moldo_code.python_modules.items():
56
+ parser.import_python_module(path)
57
+
58
+ # Compile and execute the code
59
+ python_code = parser.parse(moldo_code.code)
60
+
61
+ # Create a new namespace for execution
62
+ namespace = {}
63
+
64
+ # Execute the code
65
+ exec(python_code, namespace)
66
+
67
+ # Capture any output
68
+ output = namespace.get('__output__', '')
69
+ return ExecutionResult(output=output)
70
+ except Exception as e:
71
+ return ExecutionResult(output="", error=str(e))
72
+
73
+ @app.get("/functions")
74
+ async def get_available_functions() -> Dict[str, List[str]]:
75
+ """
76
+ Get a list of all available Moldo functions.
77
+
78
+ Returns:
79
+ Dictionary containing the list of available functions
80
+ """
81
+ return {"functions": parser.get_available_functions()}
82
+
83
+ @app.post("/functions/{name}")
84
+ async def execute_function(name: str, args: Dict[str, Any]) -> Dict[str, Any]:
85
+ """
86
+ Execute a specific Moldo function.
87
+
88
+ Args:
89
+ name: The name of the function to execute
90
+ args: The arguments to pass to the function
91
+
92
+ Returns:
93
+ Dictionary containing the function result
94
+ """
95
+ try:
96
+ result = parser.execute_function(name, **args)
97
+ return {"result": result}
98
+ except Exception as e:
99
+ raise HTTPException(status_code=400, detail=str(e))
@@ -0,0 +1,59 @@
1
+ import argparse
2
+ import sys
3
+ from pathlib import Path
4
+ from .compiler.parser import MoldoParser
5
+ from .api.server import app
6
+ import uvicorn
7
+
8
+ def compile_file(args):
9
+ """Compile a Moldo file to Python."""
10
+ parser = MoldoParser()
11
+ with open(args.input, 'r') as f:
12
+ code = f.read()
13
+
14
+ try:
15
+ python_code = parser.parse(code)
16
+ if args.output:
17
+ with open(args.output, 'w') as f:
18
+ f.write(python_code)
19
+ else:
20
+ print(python_code)
21
+ except Exception as e:
22
+ print(f"Error compiling file: {e}", file=sys.stderr)
23
+ sys.exit(1)
24
+
25
+ def run_server(args):
26
+ """Start the Moldo API server."""
27
+ uvicorn.run(
28
+ "moldo.api.server:app",
29
+ host=args.host,
30
+ port=args.port,
31
+ reload=args.reload
32
+ )
33
+
34
+ def main():
35
+ parser = argparse.ArgumentParser(description="Moldo - Visual Programming Language")
36
+ subparsers = parser.add_subparsers(dest="command", help="Command to execute")
37
+
38
+ # Compile command
39
+ compile_parser = subparsers.add_parser("compile", help="Compile Moldo code to Python")
40
+ compile_parser.add_argument("input", help="Input Moldo file")
41
+ compile_parser.add_argument("-o", "--output", help="Output Python file")
42
+ compile_parser.set_defaults(func=compile_file)
43
+
44
+ # Server command
45
+ server_parser = subparsers.add_parser("serve", help="Start the Moldo API server")
46
+ server_parser.add_argument("--host", default="127.0.0.1", help="Host to bind to")
47
+ server_parser.add_argument("--port", type=int, default=8000, help="Port to bind to")
48
+ server_parser.add_argument("--reload", action="store_true", help="Enable auto-reload")
49
+ server_parser.set_defaults(func=run_server)
50
+
51
+ args = parser.parse_args()
52
+ if args.command:
53
+ args.func(args)
54
+ else:
55
+ parser.print_help()
56
+ sys.exit(1)
57
+
58
+ if __name__ == "__main__":
59
+ main()
@@ -0,0 +1,89 @@
1
+ # Generated from moldo/compiler/Moldo.g4 by ANTLR 4.9.2
2
+ from antlr4 import *
3
+ from io import StringIO
4
+ import sys
5
+ if sys.version_info[1] > 5:
6
+ from typing import TextIO
7
+ else:
8
+ from typing.io import TextIO
9
+
10
+
11
+ def serializedATN():
12
+ with StringIO() as buf:
13
+ buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\f")
14
+ buf.write("h\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
15
+ buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\3\2\3\2\3\2\3\2\3\2")
16
+ buf.write("\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3")
17
+ buf.write("\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6")
18
+ buf.write("\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\7\7A\n\7\f\7\16\7")
19
+ buf.write("D\13\7\3\b\6\bG\n\b\r\b\16\bH\3\t\7\tL\n\t\f\t\16\tO\13")
20
+ buf.write("\t\3\n\6\nR\n\n\r\n\16\nS\3\n\3\n\3\13\3\13\3\13\3\13")
21
+ buf.write("\3\13\3\13\7\13^\n\13\f\13\16\13a\13\13\3\13\3\13\3\13")
22
+ buf.write("\3\13\3\13\3\13\4M_\2\f\3\3\5\4\7\5\t\6\13\7\r\b\17\t")
23
+ buf.write("\21\n\23\13\25\f\3\2\6\5\2C\\aac|\6\2\62;C\\aac|\4\2>")
24
+ buf.write(">@@\5\2\13\f\17\17\"\"\2l\2\3\3\2\2\2\2\5\3\2\2\2\2\7")
25
+ buf.write("\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2")
26
+ buf.write("\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\3\27\3\2\2")
27
+ buf.write("\2\5\37\3\2\2\2\7!\3\2\2\2\t+\3\2\2\2\13\64\3\2\2\2\r")
28
+ buf.write(">\3\2\2\2\17F\3\2\2\2\21M\3\2\2\2\23Q\3\2\2\2\25W\3\2")
29
+ buf.write("\2\2\27\30\7>\2\2\30\31\7o\2\2\31\32\7d\2\2\32\33\7n\2")
30
+ buf.write("\2\33\34\7q\2\2\34\35\7e\2\2\35\36\7m\2\2\36\4\3\2\2\2")
31
+ buf.write("\37 \7@\2\2 \6\3\2\2\2!\"\7>\2\2\"#\7\61\2\2#$\7o\2\2")
32
+ buf.write("$%\7d\2\2%&\7n\2\2&\'\7q\2\2\'(\7e\2\2()\7m\2\2)*\7@\2")
33
+ buf.write("\2*\b\3\2\2\2+,\7>\2\2,-\7r\2\2-.\7{\2\2./\7v\2\2/\60")
34
+ buf.write("\7j\2\2\60\61\7q\2\2\61\62\7p\2\2\62\63\7@\2\2\63\n\3")
35
+ buf.write("\2\2\2\64\65\7>\2\2\65\66\7\61\2\2\66\67\7r\2\2\678\7")
36
+ buf.write("{\2\289\7v\2\29:\7j\2\2:;\7q\2\2;<\7p\2\2<=\7@\2\2=\f")
37
+ buf.write("\3\2\2\2>B\t\2\2\2?A\t\3\2\2@?\3\2\2\2AD\3\2\2\2B@\3\2")
38
+ buf.write("\2\2BC\3\2\2\2C\16\3\2\2\2DB\3\2\2\2EG\n\4\2\2FE\3\2\2")
39
+ buf.write("\2GH\3\2\2\2HF\3\2\2\2HI\3\2\2\2I\20\3\2\2\2JL\13\2\2")
40
+ buf.write("\2KJ\3\2\2\2LO\3\2\2\2MN\3\2\2\2MK\3\2\2\2N\22\3\2\2\2")
41
+ buf.write("OM\3\2\2\2PR\t\5\2\2QP\3\2\2\2RS\3\2\2\2SQ\3\2\2\2ST\3")
42
+ buf.write("\2\2\2TU\3\2\2\2UV\b\n\2\2V\24\3\2\2\2WX\7>\2\2XY\7#\2")
43
+ buf.write("\2YZ\7/\2\2Z[\7/\2\2[_\3\2\2\2\\^\13\2\2\2]\\\3\2\2\2")
44
+ buf.write("^a\3\2\2\2_`\3\2\2\2_]\3\2\2\2`b\3\2\2\2a_\3\2\2\2bc\7")
45
+ buf.write("/\2\2cd\7/\2\2de\7@\2\2ef\3\2\2\2fg\b\13\2\2g\26\3\2\2")
46
+ buf.write("\2\b\2BHMS_\3\b\2\2")
47
+ return buf.getvalue()
48
+
49
+
50
+ class MoldoLexer(Lexer):
51
+
52
+ atn = ATNDeserializer().deserialize(serializedATN())
53
+
54
+ decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
55
+
56
+ T__0 = 1
57
+ T__1 = 2
58
+ T__2 = 3
59
+ T__3 = 4
60
+ T__4 = 5
61
+ IDENTIFIER = 6
62
+ TEXT = 7
63
+ PYTHON_CODE = 8
64
+ WS = 9
65
+ COMMENT = 10
66
+
67
+ channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
68
+
69
+ modeNames = [ "DEFAULT_MODE" ]
70
+
71
+ literalNames = [ "<INVALID>",
72
+ "'<mblock'", "'>'", "'</mblock>'", "'<python>'", "'</python>'" ]
73
+
74
+ symbolicNames = [ "<INVALID>",
75
+ "IDENTIFIER", "TEXT", "PYTHON_CODE", "WS", "COMMENT" ]
76
+
77
+ ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "IDENTIFIER",
78
+ "TEXT", "PYTHON_CODE", "WS", "COMMENT" ]
79
+
80
+ grammarFileName = "Moldo.g4"
81
+
82
+ def __init__(self, input=None, output:TextIO = sys.stdout):
83
+ super().__init__(input, output)
84
+ self.checkVersion("4.9.2")
85
+ self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache())
86
+ self._actions = None
87
+ self._predicates = None
88
+
89
+
@@ -0,0 +1,66 @@
1
+ # Generated from moldo/compiler/Moldo.g4 by ANTLR 4.9.2
2
+ from antlr4 import *
3
+ if __name__ is not None and "." in __name__:
4
+ from .MoldoParser import MoldoParser
5
+ else:
6
+ from MoldoParser import MoldoParser
7
+
8
+ # This class defines a complete listener for a parse tree produced by MoldoParser.
9
+ class MoldoListener(ParseTreeListener):
10
+
11
+ # Enter a parse tree produced by MoldoParser#program.
12
+ def enterProgram(self, ctx:MoldoParser.ProgramContext):
13
+ pass
14
+
15
+ # Exit a parse tree produced by MoldoParser#program.
16
+ def exitProgram(self, ctx:MoldoParser.ProgramContext):
17
+ pass
18
+
19
+
20
+ # Enter a parse tree produced by MoldoParser#block.
21
+ def enterBlock(self, ctx:MoldoParser.BlockContext):
22
+ pass
23
+
24
+ # Exit a parse tree produced by MoldoParser#block.
25
+ def exitBlock(self, ctx:MoldoParser.BlockContext):
26
+ pass
27
+
28
+
29
+ # Enter a parse tree produced by MoldoParser#mblock.
30
+ def enterMblock(self, ctx:MoldoParser.MblockContext):
31
+ pass
32
+
33
+ # Exit a parse tree produced by MoldoParser#mblock.
34
+ def exitMblock(self, ctx:MoldoParser.MblockContext):
35
+ pass
36
+
37
+
38
+ # Enter a parse tree produced by MoldoParser#block_type.
39
+ def enterBlock_type(self, ctx:MoldoParser.Block_typeContext):
40
+ pass
41
+
42
+ # Exit a parse tree produced by MoldoParser#block_type.
43
+ def exitBlock_type(self, ctx:MoldoParser.Block_typeContext):
44
+ pass
45
+
46
+
47
+ # Enter a parse tree produced by MoldoParser#block_content.
48
+ def enterBlock_content(self, ctx:MoldoParser.Block_contentContext):
49
+ pass
50
+
51
+ # Exit a parse tree produced by MoldoParser#block_content.
52
+ def exitBlock_content(self, ctx:MoldoParser.Block_contentContext):
53
+ pass
54
+
55
+
56
+ # Enter a parse tree produced by MoldoParser#python_block.
57
+ def enterPython_block(self, ctx:MoldoParser.Python_blockContext):
58
+ pass
59
+
60
+ # Exit a parse tree produced by MoldoParser#python_block.
61
+ def exitPython_block(self, ctx:MoldoParser.Python_blockContext):
62
+ pass
63
+
64
+
65
+
66
+ del MoldoParser