Understandable Translation Tool for Routines - A procedure-oriented programming language with plain English-like syntax
- Overview
- Features
- Project Structure
- Getting Started
- Project Roadmap
- Contributing
- License
- Acknowledgments
UTTR (Understandable Translation Tool for Routines) is a custom-built, procedure-oriented programming language featuring an intuitive, English-like syntax designed for clarity and ease of learning. Built from scratch in Python, UTTR includes a complete interpreter with lexical analysis, parsing, and runtime execution capabilities. The language emphasizes simplicity and readability, making programming concepts more accessible through natural language constructs like put 10 in x for variable assignment and show for output.
- Natural English-Like Syntax: Write code that reads like plain English with keywords like
put,in,when,otherwise,check,whether,default,make function,give,cut,skip,attempt, andhandle - Complete Interpreter: Full lexer-parser-interpreter pipeline built from scratch with comprehensive error handling and position tracking
- Procedure-Oriented Design: Focus on procedures and sequential execution with modular, reusable functions
- Module System: Import/export functionality for code organization with natural syntax (
bring in,share), standard library modules, and automatic caching - Rich Data Types: Support for integers, floats, strings, booleans, lists, tuples (immutable lists), sets (unique unordered collections), dictionaries, and regular expressions with intuitive access using
@operator for dictionaries and/for indexing - Regular Expressions: Full regex support with pattern matching using
r"pattern"syntax for text processing and validation - Operators: Arithmetic (
+,-,*,/,%), comparison (==,!=,<,>,<=,>=), logical (and,or,not), and set operations (+for union,&for intersection,-for difference,^for symmetric difference) - Control Structures: Conditional statements (
when...otherwise), switch-case statements (check...whether...default), loops (cycle,as long as,repeat while), and for-each iteration with loop control (cutfor break,skipfor continue) - Error Handling: Try-catch blocks using
attempt...handlesyntax with error introspection (error_message,error_type) - Function Support:
- Named functions with
make functionandgivekeywords - Anonymous lambda functions with inline syntax (
lambda x => x * 2) - Higher-order functions (functions as arguments/return values)
- Named functions with
- Built-in Functions: Pre-defined utilities including:
- I/O:
show,input,input_int - Collections:
len,append,pop,extend - Tuples:
tuple(convert to tuple),list(convert to list) - Sets:
union,intersection,difference,symmetric_difference,add,remove,contains,is_subset,is_superset,set_from_list - Dictionaries:
keys,values,has_key,remove - Strings:
split,join,upper,lower,replace,substring - Regular Expressions:
regex_match,regex_search,regex_replace,regex_findall,regex_split - Error handling:
error_message,error_type - Execution:
run(execute external .uttr files)
- I/O:
- Standard Library: Built-in modules for common tasks:
math: Mathematical functions (sqrt, pow, abs, max, min, etc.) and constants (PI, E)lists: List utilities (range, sum, reverse, contains, etc.)strings: String operations (starts_with, ends_with, repeat, capitalize, etc.)
- Variable & Constant Management: Mutable variables with
put...inand immutable constants withkeep...as - Comment Support: Single-line (
$) and multi-line ($[...]$) comments for code documentation - Interactive REPL: Test code snippets interactively or run complete
.uttrfiles - Comprehensive Error Reporting: Detailed error messages with line and column information using visual arrows
UTTR/
__root__
interpreter.py Executes the abstract syntax tree (AST) by visiting nodes and performing operations based on the language's runtime semantics strings_with_arrows.py Generates visual error indicators with arrows pointing to specific error locations in source code for better debugging lexer_testing.py Testing utility for validating the lexer's tokenization process with various input patterns parser.py Transforms token stream into an abstract syntax tree (AST) according to UTTR's grammar rules symbol_table.py Manages variable and constant storage with scope hierarchy for runtime symbol lookup and assignment context.py Maintains execution context information including function call stack and symbol tables position.py Tracks line, column, and character positions in source code for accurate error reporting constants.py Defines character sets (digits, letters) used throughout the lexer for token recognition lexer.py Converts raw source code into tokens for parsing, handling keywords, operators, literals, and comments run_time_result.py Wraps interpreter execution results with success/error status and return value handling parse_result.py Encapsulates parser output with AST nodes and error information for downstream processing entry.py Main entry point coordinating lexer, parser, and interpreter with global symbol table initialization shell.py Interactive REPL and file runner for executing UTTR programs from command line or interactively tokens.py Defines all token types and keywords recognized by the UTTR language lexer
nodes
const_assign_node.py AST node representing constant declarations with immutability semantics dict_node.py AST node representing dictionary literals with key-value pairs for_node.py AST node for range-based for loops with start, end, and step expressions list_access_node.py AST node for list element access using index notation unary_operator_node.py AST node for unary operations like negation and logical NOT string_node.py AST node representing string literal values binary_operator_node.py AST node for binary operations including arithmetic, comparison, and logical operators if_node.py AST node for conditional statements with if, elif, and else branches for_each_node.py AST node for iterating over collections with for-each semantics function_definition_node.py AST node defining function declarations with parameters and body call_node.py AST node for function invocation with argument evaluation while_node.py AST node for while loop constructs with condition checking do_while_node.py AST node for do-while loop constructs (executes body before checking condition) number_node.py AST node representing numeric literal values (integers and floats) var_assign_node.py AST node for variable assignment and reassignment operations return_node.py AST node handling function return statements with value expressions cut_node.py AST node for break statements (loop early exit) skip_node.py AST node for continue statements (skip to next loop iteration) attempt_handle_node.py AST node for attempt...handle error handling blocks list_node.py AST node representing list literals with element expressions var_access_node.py AST node for variable and constant value retrieval from symbol table
functions
builtin_function.py Implements standard library functions (show, input, len, append, pop, extend, run) with argument validation function.py Manages user-defined functions with parameter binding and execution context setup base_function.py Abstract base class defining common function interface and execution patterns
values
number_value.py Runtime representation of numeric values with arithmetic and comparison operations dict_value.py Runtime representation of dictionary/map collections with key-based access and manipulation operations error_value.py Runtime representation of caught errors with message, type, and details for error handling value.py Base class for all runtime values with position tracking and context management string_value.py Runtime representation of string values with concatenation and comparison support list_value.py Runtime representation of list collections with indexing, concatenation, and mutation operations set_value.py Runtime representation of set collections with unique elements and set operations (union, intersection, difference)
errors
invalid_syntax.py Error class for syntax violations during parsing with expected token information illegal_character.py Error class for unrecognized characters encountered during lexical analysis error.py Base error class with position tracking and formatted error message generation run_time_error.py Error class for runtime exceptions with execution context and traceback information
examples
conditionals.uttr Demonstrates conditional branching with when/otherwise statements dictionaries.uttr Shows dictionary creation, key-based access, and built-in dictionary functions lists.uttr Shows list creation, indexing, and manipulation operations for_loop.uttr Illustrates range-based iteration with cycle keyword for_each_loop.uttr Demonstrates iteration over collections using for-each semantics constants.uttr Examples of immutable constant declarations with keep/as syntax while_loop.uttr Shows condition-based looping with as long as construct do_while_loop.uttr Demonstrates do-while loops (repeat while) that execute at least once functions.uttr Function definition, invocation, and return value examples variables.uttr Basic variable declaration and assignment with put/in syntax nested_condition_and_loop.uttr Complex control flow with nested conditionals and loops function_with_list.uttr Functions working with list parameters and operations comments.uttr Demonstrates single-line and multi-line comment syntax break_continue.uttr Examples of loop control with cut (break) and skip (continue) statements modulo.uttr Demonstrates modulo operator (%) usage for divisibility checks and patterns attempt_handle.uttr Demonstrates attempt...handle error handling with error introspection and recovery patterns tuples.uttr Demonstrates tuple (immutable list) creation, indexing, concatenation, and conversion with `<>` syntax
tests
run_tests.py Automated test runner that executes all test files and reports pass/fail statistics README.md Comprehensive documentation for the test suite with usage instructions Test Files 48 test files covering all language features: variables, arithmetic, comparisons, logical operations, strings, conditionals, loops (for/while/do-while/for-each), lists, tuples, sets, dictionaries, list/dict/set mutations, functions, built-ins, comments, errors, break/continue, modulo operator, and integration tests
Before getting started with uttr, ensure your runtime environment meets the following requirements:
- Programming Language: Python 3.7+
Install uttr using one of the following methods:
Build from source:
- Clone the uttr repository:
β― git clone https://github.com/THAMIZH-ARASU/uttr- Navigate to the project directory:
β― cd uttr- Install the project dependencies:
No external dependencies required - UTTR uses only Python standard library
Run uttr using the following command:
Interactive REPL Mode:
β― python shell.pyExecute a .uttr file:
β― python shell.py examples/variables.uttrExample Code:
$ Variable declaration
put 42 in answer;
show answer;
$ Function definition
make function greet(name):
show "Hello, " + name + "!";
end;
greet("World");
$ For loop with step
cycle i from 0 to 10 step 2:
show i;
end;
$ Loop control with cut (break) and skip (continue)
cycle i from 0 to 20:
when i > 10:
cut; $ Exit loop early
end;
when i == 5:
skip; $ Skip to next iteration
end;
show i;
end;
$ Modulo operator for patterns
cycle i from 1 to 16:
when i % 15 == 0:
show "FizzBuzz";
end;
when i % 3 == 0:
show "Fizz";
end;
when i % 5 == 0:
show "Buzz";
end;
end;
$ Dictionary creation and access
put {"name": "Alice", "age": 25, "city": "NYC"} in person;
show "Name: " + person @ "name";
show "Age: " + person @ "age";
$ Dictionary operations
put keys(person) in all_keys;
show "Has 'email' key: " + has_key(person, "email");
$ String methods
put "hello world from uttr" in text;
put upper(text) in uppercase;
show uppercase;
put split(text, " ") in words;
show "Word count: " + len(words);
put join(words, "-") in joined;
show joined;
put replace(text, "uttr", "UTTR") in replaced;
show replaced;
put substring(text, 0, 5) in first_word;
show first_word;
$ Tuples - immutable lists with <> syntax
put <1, 2, 3, 4, 5> in immutable_tuple;
show "Tuple: " + immutable_tuple;
show "Length: " + len(immutable_tuple);
show "First element: " + immutable_tuple / 0;
$ Tuple concatenation
put <1, 2, 3> in t1;
put <4, 5, 6> in t2;
put t1 * t2 in combined;
show "Combined tuple: " + combined;
$ Convert between list and tuple
put [1, 2, 3] in mutable_list;
put tuple(mutable_list) in as_tuple;
put list(as_tuple) in back_to_list;
show "As tuple: " + as_tuple;
$ Tuple immutability - this will cause an error
attempt:
put immutable_tuple + 6 in modified;
end
handle as error:
show "Error: " + error_message(error);
end;
$ Sets - unique unordered collections with {: :} syntax
put {: 1, 2, 3, 4, 5 :} in set_a;
put {: 4, 5, 6, 7, 8 :} in set_b;
show "Set A: " + set_a;
show "Set B: " + set_b;
$ Set operations
put set_a + set_b in union_result;
show "Union (A + B): " + union_result;
put set_a & set_b in intersection_result;
show "Intersection (A & B): " + intersection_result;
put set_a - set_b in difference_result;
show "Difference (A - B): " + difference_result;
put set_a ^ set_b in symmetric_diff;
show "Symmetric Difference (A ^ B): " + symmetric_diff;
$ Set operations with built-in functions
put union(set_a, set_b) in union_func;
put intersection(set_a, set_b) in inter_func;
$ Automatic duplicate removal
put {: 1, 2, 2, 3, 3, 3 :} in deduped;
show "Deduplicated: " + deduped; $ Output: {: 1, 2, 3 :}
$ Set membership and operations
put contains(set_a, 3) in has_three;
show "Set A contains 3: " + has_three;
put add(set_a, 10) in set_with_10;
show "After adding 10: " + set_with_10;
show "Original unchanged: " + set_a; $ Sets are immutable
$ Subset and superset checks
put {: 1, 2, 3 :} in small_set;
put is_subset(small_set, set_a) in is_sub;
show "Is subset: " + is_sub;
$ Convert list to set
put [1, 2, 2, 3, 3, 3] in list_with_dups;
put set_from_list(list_with_dups) in unique_set;
show "Unique values: " + unique_set;
$ Try-catch error handling
make function safe_divide(a, b):
attempt:
give a / b;
end
handle as error:
show "Error: " + error_message(error);
give 0;
end
end;
put safe_divide(10, 2) in result;
show "Result: " + result;
put safe_divide(10, 0) in result;
show "Result: " + result; $ Handles error gracefully
$ Lambda functions - anonymous functions with inline syntax
put lambda x => x * 2 in double;
show "Double of 5: " + double(5);
$ Lambda with multiple parameters
put lambda a, b => a + b in add;
show "3 + 7 = " + add(3, 7);
$ Lambda as function argument (higher-order functions)
make function apply(func, value):
give func(value);
end;
show "Apply square: " + apply(lambda x => x * x, 4);
$ Lambda with list processing
make function map_list(func, list):
put [] in result;
cycle i from 0 to len(list):
append(result, func(list / i));
end;
give result;
end;
put [1, 2, 3, 4, 5] in numbers;
put map_list(lambda x => x * x, numbers) in squares;
show "Squares: " + squares;
UTTR includes a powerful module system for organizing code into reusable libraries.
Import Syntax:
$ Import entire module
bring in math;
$ Import specific items
bring sqrt, pow from math;
$ Import with alias
bring sqrt as square_root from math;
$ Import multiple items with aliases
bring add as sum, multiply as product from calculator;
Export Syntax:
$ In your module file (mymodule.uttr)
make function helper():
give "I'm exported!";
end;
$ Explicitly export specific items
share helper;
$ Without share statement, all top-level definitions are exported automatically
Standard Library Modules:
-
math: Mathematical operations
- Constants:
PI,E - Functions:
abs,pow,max,min,round,floor,ceil,sqrt
- Constants:
-
lists: List utilities
- Functions:
range,sum,max_list,min_list,reverse,contains
- Functions:
-
strings: String operations
- Functions:
starts_with,ends_with,trim,count_occurrences,repeat,capitalize
- Functions:
Module Search Paths:
- Current directory of the importing file (for relative imports)
- Current working directory
- Standard library directory (
stdlib/)
Example - Creating a Custom Module:
$ File: calculator.uttr
make function add(a, b):
give a + b;
end;
make function multiply(a, b):
give a * b;
end;
share add, multiply;
$ File: main.uttr
bring add, multiply from calculator;
show add(10, 20); $ Output: 30
show multiply(5, 7); $ Output: 35
See examples/modules/ for more examples.
Technical Notes:
- Function Context Preservation: When a function is imported from a module, it preserves its original defining context. This allows functions to access other symbols (variables, functions) defined in their module, even when called from a different module.
- Module Caching: Modules are executed once and cached. Subsequent imports reuse the cached module.
- Circular Import Detection: The module loader detects and prevents circular dependencies.
- Path Resolution: Module paths support subdirectories using forward slashes (e.g.,
subdir/module). Absolute file system paths are not supported to maintain portability. - Export Behavior: Without an explicit
sharestatement, all non-underscore top-level definitions are exported. Use underscore prefix (e.g.,_helper_func) for private functions.
UTTR includes comprehensive regular expression support for pattern matching and text processing using Python's re module under the hood.
Regex Literal Syntax:
Use the r"pattern" syntax (similar to Python raw strings) to create regex patterns:
put r"\d{3}-\d{4}" in phone_pattern;
put r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" in email_pattern;
Built-in Regex Functions:
-
regex_match(pattern, text) - Check if pattern matches from the start of string
put r"hello" in pattern; put regex_match(pattern, "hello world") in result; $ Returns match object -
regex_search(pattern, text) - Search for pattern anywhere in string
put r"\d+" in pattern; put regex_search(pattern, "I have 42 apples") in result; when result: show "Found: " + result @ "matched_text"; show "At position: " + result @ "start_pos"; end;Returns a dictionary with:
matched_text,start_pos,end_pos,groups(list of captured groups) -
regex_replace(pattern, replacement, text) - Replace all pattern matches
put r"\d+" in pattern; put regex_replace(pattern, "X", "I have 42 apples") in result; $ Result: "I have X apples" -
regex_findall(pattern, text) - Find all matches and return as list
put r"\d+" in pattern; put regex_findall(pattern, "1 and 2 and 3") in numbers; $ Result: ["1", "2", "3"] -
regex_split(pattern, text) - Split string by pattern
put r"\s+" in pattern; put regex_split(pattern, "one two three") in words; $ Result: ["one", "two", "three"]
Common Use Cases:
$ Email validation
make function is_valid_email(email):
put r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" in pattern;
put regex_match(pattern, email) in match;
when match:
give 1;
end;
otherwise:
give 0;
end;
end;
$ Extract phone numbers
put "Contact: 555-1234 or 555-5678" in text;
put r"\d{3}-\d{4}" in phone_pattern;
put regex_findall(phone_pattern, text) in phones;
show phones; $ ["555-1234", "555-5678"]
$ Clean up whitespace
put "Too many spaces" in messy;
put r"\s+" in spaces_pattern;
put regex_replace(spaces_pattern, " ", messy) in clean;
show clean; $ "Too many spaces"
$ URL parsing with groups
put "https://example.com:8080/path" in url;
put r"(https?)://([^:]+):(\d+)(/.*)" in pattern;
put regex_search(pattern, url) in match;
when match:
put match @ "groups" in parts;
show "Protocol: " + parts / 0; $ "https"
show "Domain: " + parts / 1; $ "example.com"
show "Port: " + parts / 2; $ "8080"
show "Path: " + parts / 3; $ "/path"
end;
Error Handling:
Invalid regex patterns are caught at runtime:
attempt:
put r"[invalid(" in bad_pattern;
put regex_match(bad_pattern, "test") in result;
end
handle as error:
show "Regex error: " + error_message(error);
end;
See examples/regex_basics.uttr for more examples.
UTTR includes a comprehensive test suite covering all language features. Run tests using:
Run all tests:
> python tests/run_tests.pyRun all tests with their output:
> Get-ChildItem tests\test_*.uttr | ForEach-Object { Write-Host "`n=== Testing $($_.Name) ==="; python shell.py $_.FullName }Run individual test files:
> python shell.py tests/test_variables.uttr
> python shell.py tests/test_tuples.uttr
> python shell.py tests/test_sets.uttr
> python shell.py tests/test_dictionaries.uttr
> python shell.py tests/test_functions.uttr
> python shell.py tests/test_break_continue.uttr
> python shell.py tests/test_modulo.uttr
> python shell.py tests/test_imports.uttrTest lexer output:
> python lexer_testing.py <file_name>The test suite includes 48 test files with 300+ individual tests covering:
- Variables and constants
- Arithmetic and comparison operations
- Modulo operator (
%) for divisibility checks - Logical operations
- String operations with escape sequences
- Conditional statements
- All loop types (for, while, do-while, for-each)
- Loop control (break with
cut, continue withskip) - Try-catch error handling (
attempt...handlewith error introspection) - Lists, tuples (immutable lists), sets (unique unordered collections), and dictionaries
- List mutations (append, pop, extend), dictionary mutations (remove), and set operations
- Tuple immutability and conversions
- Set operations (union, intersection, difference, symmetric difference)
- Functions and built-ins
- Lambda/anonymous functions with inline syntax
- Module system (imports, exports, standard library, error handling)
- Regular expressions (pattern matching, search, replace, findall, split)
- Comments and error handling
- Complex integration scenarios
-
Task 1:Implement lexer with tokenization for all language constructs -
Task 2:Build parser to generate AST from tokens -
Task 3:Create interpreter with runtime execution -
Task 4:Add support for functions, loops, and conditionals -
Task 5:Implement comprehensive error handling with position tracking -
Task 6:Add do-while loop support with repeat while keyword -
Task 7:Add support for dictionaries/maps data structure -
Task 8:Add break and continue statements for loop control (cutandskipkeywords) -
Task 9:Add modulo operator (%) for arithmetic operations -
Task 10:Fix list/dictionary mutation functions (append, pop, extend, remove) -
Task 11:Implement try-catch error handling (attempt...handlesyntax) -
Task 12:Add built-in methods for strings (split, join, upper, lower, replace, substring) -
Task 13:Support for tuple data type (immutable lists with<>syntax) -
Task 14:Add import/module system for code organization -
Task 15:Implement lambda/anonymous functions with inline syntax (lambda x => x * 2) -
Task 16:Add switch-case statements (check...whether...defaultsyntax) -
Task 17:Support for regular expressions with pattern matching (r"pattern"syntax,regex_match,regex_search,regex_replace,regex_findall,regex_split) -
Task 18:Add set data type with set operations (union, intersection, difference, symmetric difference)
-
Task 19: Implement list comprehensions with natural syntax -
Task 20: Add dictionary comprehensions -
Task 21: Support for multiple return values from functions -
Task 22: Implement variadic functions (variable argument count) with natural syntax -
Task 23: Support for ternary conditional expressions
-
Task 22: Add file I/O operations (read_file, write_file, append_file) -
Task 23: Implement JSON parsing and generation functions
-
Task 24: Add file I/O operations (read_file, write_file, append_file) -
Task 25: Implement JSON parsing and generation functions -
Task 26: Add CSV file reading and writing capabilities -
Task 27: Support for command-line arguments in .uttr files
-
Task 28: Add math functions (sqrt, pow, abs, round, floor, ceil, sin, cos, tan) -
Task 29: Implement random number generation functions -
Task 30: Add date and time manipulation functions -
Task 31: Create string formatting utilities (template-based approach) -
Task 32: Add list sorting and filtering built-in functions -
Task 33: Implement type checking and conversion functions
-
Task 34: Optimize interpreter with bytecode compilation -
Task 35: Implement caching for frequently used expressions -
Task 36: Add tail call optimization for recursive functions -
Task 37: Create AST optimization passes before interpretation
-
Task 38: Add Python interop to call Python libraries from UTTR -
Task 39: Create UTTR-to-Python transpiler for performance -
Task 40: Support for calling external executables/shell commands -
Task 41: Add HTTP client functions for web requests
-
Task 42: Create interactive tutorial website for UTTR -
Task 43: Add more complex example projects -
Task 44: Create video tutorials for language features
-
Task 45: Expand test coverage to 100% of codebase -
Task 46: Add benchmark suite to track performance over time -
Task 47: Implement fuzzing tests for parser robustness
-
Task 48: Build debugging tools with breakpoint support -
Task 49: Add code formatter/prettifier for UTTR files -
Task 50: Create syntax highlighting extension for VS Code -
Task 51: Implement static type checking (optional type annotations) -
Task 52: Create linter for code quality and style enforcement -
Task 53: Add performance profiler to identify bottlenecks
- π¬ Join the Discussions: Share your insights, provide feedback, or ask questions.
- π Report Issues: Submit bugs found or log feature requests for the
uttrproject. - π‘ Submit Pull Requests: Review open PRs, and submit your own PRs.
Contributing Guidelines
- Fork the Repository: Start by forking the project repository to your github account.
- Clone Locally: Clone the forked repository to your local machine using a git client.
git clone https://github.com/THAMIZH-ARASU/uttr
- Create a New Branch: Always work on a new branch, giving it a descriptive name.
git checkout -b new-feature-x
- Make Your Changes: Develop and test your changes locally.
- Commit Your Changes: Commit with a clear message describing your updates.
git commit -m 'Implemented new feature x.' - Push to github: Push the changes to your forked repository.
git push origin new-feature-x
- Submit a Pull Request: Create a PR against the original project repository. Clearly describe the changes and their motivations.
- Review: Once your PR is reviewed and approved, it will be merged into the main branch. Congratulations on your contribution!
This project is protected under the MIT License. For more details, refer to the LICENSE file.
- Inspired by the desire to create a more readable and intuitive programming language for beginners
- Built with Python's powerful language processing capabilities
- Thanks to the open-source community for tools and inspiration