ParsLang is a simple, interpreted scripting language designed with educational purposes in mind. It features a straightforward syntax, basic data types, control flow structures, functions, and notably, multilingual keyword support, allowing keywords to be written in both English and Persian (Farsi).
The interpreter is built from the ground up using Python, demonstrating the core components of a language processor: Lexer, Parser, and Interpreter.
Let's look at a classic example: calculating Fibonacci numbers.
1. Using English Keywords (fibo.txt)
var a = 0
var b = 1
print(a)
print(b)
for n = 1 to 10 then
var temp = a + b
a = b
b = temp
print(b)
end
print("Done!")2. Using Persian Keywords (fibo-fa.txt - equivalent logic)
موگوم عدداول = 0
موگوم عدددوم = 1
bechup(عدداول)
bechup(عدددوم)
واسه n = 1 تا 10 اووخ
موگوم موقت = عدداول + عدددوم
عدداول = عدددوم
عدددوم = موقت
bechup(عدددوم)
تمام
bechup("تمام شد!")Running the examples:
You can run these scripts using the parslang.py interpreter or the pre-built executable:
# Using Python interpreter
python parslang.py fibo.txt
python parslang.py fibo-fa.txt
# Or using the executable (Windows example, adapt for Linux/macOS)
./parslang.exe fibo.txt
./parslang.exe fibo-fa.txt- Simple Syntax: Designed to be easy to read and write.
- Variables: Dynamically typed variables using
var(orlet,موگوم,قرارده). - Data Types: Supports Numbers (Integers and Floats), Strings, and Lists.
- Arithmetic Operations:
+,-,*,/,%(remainder),^(power). - Comparison Operators:
==,!=,<,>,<=,>=. - Logical Operators:
and,or,not(and Persian equivalents likeو,یا,نه). - Conditional Statements:
if/elif/elseblocks (usingthenandend, or single-line expressions). Persian equivalents likeاگر/مگر/وگرنهare supported. - Loops:
forloops (for i = start to end step value then ... end). Persian:برای/واسه.whileloops (while condition then ... end). Persian:هنگامیکه.
- Functions: Define functions using
fun(ordef). Supports named and anonymous functions, argument passing, and return values (returnor implicit return for arrow functions). Persian:تابع. - Lists: Create lists using
[...]. Basic list manipulation is available via built-in functions. - 🌍 Multilingual Keywords: Core language keywords have both English and Persian equivalents (see
components/CONSTANTS.pyfor the full map). - Identifier Support: Variable and function names can include Persian letters.
- Built-in Functions: Provides essential functions like
print,input, type checking, list operations, etc. - Error Handling: Clear error messages with tracebacks and code highlighting pointing to the error location.
- Comments: Single-line comments using
#.
Declare variables using var (or aliases like let, موگوم). Assignment uses =. If no value is assigned, it defaults to 0.
var message = "Hello, ParsLang!"
var count = 10
var pi = 3.14
var xSupports multi-line blocks with then and end, or single-line expressions.
var grade = 75
if grade >= 90 then
print("A")
elif grade >= 80 then
print("B")
else
print("C or lower")
end
var result = if grade > 50 then "Pass" else "Fail"
print(result)
اگر grade >= 90 اووخ
bechup("عالی")
مگر grade >= 80 اووخ
bechup("خوب")
وگرنه
bechup("نیاز به تلاش بیشتر")
تمامFor Loop: Iterates over a range of numbers.
for i = 1 to 5 then
print(i)
end
for j = 10 to 0 step -2 then
print(j)
end
# Single-line (creates a list of results)
var squares = for x = 1 to 4 then x * x
print(squares)
واسه i = 1 تا 3 اووخ
bechup(i)
تمامWhile Loop: Executes as long as a condition is true.
var counter = 0
while counter < 3 then
print(counter)
counter = counter + 1
end
var vals = while counter < 5 then counter = counter + 1 # Note: depends on expression evaluated
هنگامیکه counter < 6 اووخ
bechup(counter)
counter = counter + 1
تمامDefine reusable blocks of code.
fun greet(name)
print("Hello, " + name)
end
greet("World")
fun add(x, y)
return x + y
end
var sum = add(5, 3)
print(sum) # Output: 8
fun multiply(a, b) -> a * b
print(multiply(4, 5))
var power = fun (base, exp) -> base ^ exp
print(power(2, 3)) # Output: 8
تابع سلام(اسم)
bechup("سلام، " + اسم)
تمام
سلام("دنیا")Ordered collections of items.
var my_list = [1, "two", 3.0, true]
print(my_list)
append(my_list, "new")
print(my_list)
var item = pop(my_list, 1)
print(item)
print(my_list)
var another_list = [4, 5]
extend(my_list, another_list)
print(my_list)
print(len(my_list))ParsLang provides several built-in functions (available globally):
print(value): Prints the string representation of a value to the console.print_ret(value): Returns the string representation of a value (doesn't print).input(): Reads a line of text input from the user, returns it as a String.input_int(): Reads input, ensuring it's an Integer, and returns it as a Number. Reprompts if input is invalid.clear(): Clears the console screen.is_number(value): Returnstrueif the value is a Number,falseotherwise.is_string(value): Returnstrueif the value is a String,falseotherwise.is_list(value): Returnstrueif the value is a List,falseotherwise.is_function(value): Returnstrueif the value is a Function,falseotherwise.append(list, value): Addsvalueto the end oflist.pop(list, index): Removes and returns the element atindexfromlist.extend(list1, list2): Appends all elements fromlist2to the end oflist1.len(list): Returns the number of elements inlistas a Number.run(filename): Executes the ParsLang script contained in the file specified by thefilenamestring.
(Note: Persian equivalents for these function names are planned but not yet implemented - see To-Do).
ParsLang aims to provide helpful error messages:
- Lexical Errors: Catches invalid characters (
IllegalCharError). - Syntax Errors: Detects incorrect grammar or structure (
InvalidSyntaxError,ExpectedCharError). - Runtime Errors: Handles errors during execution, like division by zero, undefined variables, type mismatches, or incorrect function arguments (
RuntimeError).
Errors include:
- The type of error.
- A specific error message.
- The filename and line number where the error occurred.
- A traceback showing the function call stack.
- The line(s) of code causing the error, with
^characters pointing to the problematic segment.
1. Interactive Shell
Run the interactive shell to experiment with ParsLang commands directly:
python shell.pyYou'll get a Persian basic > prompt. Type ParsLang code and press Enter. Type exit or Ctrl+C to quit.
2. Running .pars Files
Save your ParsLang code in a file with a .pars extension (e.g., my_script.pars). Then run it using parslang.py:
python parslang.py my_script.pars3. Using the Executables (No Python Installation Needed!)
Pre-built executables (shell.exe, parslang.exe on Windows; shell, parslang on Linux/macOS) are provided in the repository (or you can build them yourself using PyInstaller). These allow you to run the shell or scripts without having Python installed on the system.
# Windows Example
./shell.exe
./parslang.exe my_script.pars
# Linux/macOS Example (ensure execute permission: chmod +x shell parslang)
./shell
./parslang my_script.parsThe interpreter is broken down into several key components:
shell.py: The interactive Read-Eval-Print Loop (REPL).parslang.py: The script runner for.parsfiles.grammar.txt: Defines the language's grammar rules (useful for understanding structure, though not directly used by this specific parser implementation which is recursive descent).components/: Core interpreter modules.CONSTANTS.py: Defines keywords (English/Persian), character sets, etc.POSITION.py: Tracks file, line, and column numbers for error reporting.TOKENS.py: Defines token types (likeTT_INT,TT_PLUS,TT_IDENTIFIER,TT_KEYWORD).ERRORS.py: Defines custom error classes (IllegalCharError,InvalidSyntaxError,RuntimeError).LEXER.py: Scans the source text and converts it into a stream of tokens (Tokenization).NODES.py: Defines the Abstract Syntax Tree (AST) node types (e.g.,NumberNode,BinOpNode,ifNode).PARSE_RESULT.py: Helper class for the parser to manage results and errors.PARSER.py: Takes the token stream from the Lexer and builds an AST based on the language grammar.RUNTIME_RESULT.py: Helper class for the interpreter to manage results, errors, and control flow signals (return, break, continue).CONTEXT.py: Manages the execution context, including the symbol table and parent context (for scope).SYMBOL_TABLE.py: Stores variable and function names and their corresponding values within a scope.INTERPRETER.py: Traverses the AST generated by the Parser and executes the code (Evaluation).VALUES/: Defines the runtime value types.VALUE.py: Base class for all runtime values.NUMBER.py: Represents numeric values.STRING.py: Represents string values.LIST.py: Represents list values.BASE_FUNCTION.py: Base class for functions.- (Implementation Note:
Functionis defined withinINTERPRETER.py,BuiltinFunctionwithinBUILTIN_FUNCTIONS.py).
BUILTIN_FUNCTIONS.py: Defines and implements the built-in functions, and includes the mainrunfunction orchestrating the Lexer, Parser, and Interpreter.
utils/: Utility functions.strings_with_arrows.py: Generates the code snippet with arrows for error reporting.mapPersian2EnglishAlphabet.py: Maps Persian letters to their English phonetic equivalents (used internally for potential keyword matching logic, though the primary mapping is inCONSTANTS.py).makeToken.py: Helper function example for token creation (actual logic is inLEXER.py).persianDigit2English.py: Converts Persian digits (۰-۹) to English digits (0-9) during lexing.
- Better Error Messages: Provide more context-specific suggestions for syntax errors.
- Translate Built-in Functions: Allow calling built-in functions using Persian names (e.g.,
چاپforprint). - More Data Types: Consider adding explicit Booleans (
true/falsecurrently map to Numbers 1/0) or Dictionaries/Maps. - Standard List Indexing: Implement
my_list[index]syntax for accessing and potentially assigning list elements. - More Built-in Functions: Add functions for math operations, string manipulation, file I/O, etc.
- Unit Tests: Develop a comprehensive test suite to ensure correctness and prevent regressions.
- Documentation: Auto-generate documentation from code comments or write more detailed language specs.
- Modules/Imports: Add a system for importing code from other ParsLang files.
- Comments Bug Fix fix comments when have multiline and when have comments infront of an statemnet.
Contributions are welcome! If you'd like to help improve ParsLang:
- Fork the repository.
- Create a new branch for your feature or bug fix (
git checkout -b feature/your-feature-name). - Make your changes.
- Commit your changes (
git commit -am 'Add some feature'). - Push to the branch (
git push origin feature/your-feature-name). - Create a new Pull Request.
Please explain your changes clearly in the pull request description.
Ahmad Reza Anaami - [email protected]
Feel free to reach out with questions, suggestions, or feedback!
MIT License
Copyright (c) 2025 SAhmadrezaAnaami
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.