dongbei Programming Language

repository·master·Indexed 25 days ago

https://github.com/zhanyong-wan/dongbei

A human-centric and entertaining programming language built on top of Python 3 that uses Northeast Chinese dialect (Dongbei) vocabulary as its primary keywords. It features a full execution pipeline including tokenization, parsing via Lark, and translation to Python code. The language supports variables, collections (群众), tuples (抱团), control flow (寻思, 磨叽), functions (套路), and classes (阶级), and allows importing Python modules using the 帮衬 syntax.

Tokens
7.3K
Snippets
32
Records
59
Agent score
78%

What's inside dongbei

  1. Lexical Rules in dongbei

    master

    String Constants

    Use matching full-width Chinese double quotes (“...”) to define string constants.

    Comments

    Use the # character to start a comment. Everything from # to the end of the line is ignored, provided it is outside of a string constant.

    Tokenization

    The language is whitespace-insensitive. Spaces and newlines do not act as delimiters and can be added or removed without changing the logic (except inside string constants).

    Naming and Brackets

    Variables, functions, and types are called names. Because the language does not use spaces to separate names from keywords, you must use full-width Chinese square brackets 【】 to disambiguate names that contain keywords.

    Example: 【阶乘】 ensures the name is treated as a single entity even if it contains the keyword .

  2. Understand the dongbei execution pipeline

    master

    The dongbei interpreter follows a four-step pipeline to transform source code into execution:

    1. Tokenization (tokenize()): Breaks the source code into a list of Token objects.
    2. Parsing (translate_tokens_to_statements()): Uses the Lark parser to convert the token list into a syntax tree (Statement objects).
    3. Translation (translate_statement_to_python()): Converts each node in the syntax tree into a corresponding Python string.
    4. Execution (exec()): Runs the generated Python code using the standard Python exec() function.

    The main entry point for this process is translate_and_run().

  3. Set up the dongbei development environment

    master

    To start contributing to dongbei, you need to install the dependencies and verify the environment by running all tests and demos. The project relies on Python 3.

    1. Install required dependencies using pip.
    2. Run the test suite to ensure everything is working correctly. The test_all script runs all unit tests and executes every .dongbei file in the demo/ directory.
    pip install -r requirements.txt
    bash test/test_all
  4. Work with Groups (Arrays)

    master

    Creating and Modifying Groups

    • Initialize: NAME是活雷锋。 creates an empty group. Use NAME 装 「val1, val2」 to initialize with values.
    • Add element: NAME 来了个 VALUE。 adds an element to the end.
    • Add multiple: NAME 来了群 GROUP_NAME。 or NAME 来了群 「val1, val2」。
    • Count elements: NAME 有几个坑。
    • Remove element: 炮决 NAME.第N个。 (e.g., 炮决张家庄的老三。)
    • Clear group: 削 NAME。 removes all elements but keeps the name.

    Accessing Elements

    Use ordinal names to access elements:

    • 老大 (First)
    • 老二 (Second)
    • 老幺 (Last)
    • 老一 (Same as First)

    Group Operations

    • 掐头 : Returns a new group excluding the first element.
    • 去尾 : Returns a new group excluding the last element.
  5. Define and Use Routines (套路)

    master

    Defining a Routine

    套路名字 咋整:
      ... 
    整完了。

    Calling a Routine

    Use 整 套路名。 to execute it.

    Parameterized Routines

    Define parameters in parentheses:

    【套路名】(参数1, 参数2) 咋整:
      ... 
    整完了。

    Call it with: 整【套路名】(值1, 值2)。

    Returning Values

    Use 滚犊子吧 VALUE。 to return a value from a routine.

    Nested Routines

    You can define a routine inside another routine. The inner routine is only visible within the scope of the outer routine.

    【阶乘】(那啥) 咋整:
      老王装一。
      老李从一到那啥磨叽:
        老王装老王乘老李。
      磨叽完了。
      滚犊子吧老王!
    整完了。
    
    嘀咕:整【阶乘】(五)。
  6. Use Classes (阶级)

    master

    Defining a Class

    Classes are defined using inheritance syntax: PARENT_CLASS 的接班银 CHILD_CLASS 咋整: ... 整完了。

    Initializing Objects

    Define an initializer inside the class:

    无产阶级的接班银 有名 阶级咋整:
      新对象(参数) 咋整:
        俺的 属性 装 参数。
      整完了。
    整完了。

    Using Class Properties and Methods

    • : A special keyword referring to the current object instance.
    • Methods: Define routines inside a class to act as methods.
    • Inheritance: A child class inherits all properties and methods from its parent.

    Example of calling a method: object_name 整 method_name。

    有名 阶级的接班银 特有名 阶级咋整:
      新对象咋整:
        整 领导的新对象(“赵英俊”)。
        俺的 年龄 装 25。
      整完了。
    整完了。
    
    老赵 装 特有名 的新对象。
    嘀咕:老赵 的 年龄。 # 25
  7. Implement a new expression in dongbei

    master

    To add a new expression, you must create a subclass of Expr. Unlike statements, which are handled in translate_statement_to_python(), expressions require a dedicated class.

    An Expr subclass must implement four mandatory methods:

    1. equals(self, other): Used for equality comparison in unit tests.
    2. to_python(self): Generates the Python expression string for code generation.
    3. to_dongbei(self): Generates a human-readable Dongbei description for error messages when assertions fail.
    4. __str__(self): Provides a string representation.

    After defining the class, add the new expression rules to the appropriate grammar rules (e.g., expr or atomic_expr) in the parser using a Transformer method.

    class AbsExpr(Expr):
        def __init__(self, expr):
            self.expr = expr
    
        def __str__(self):
            return f"ABS_EXPR<{self.expr}>"
    
        def equals(self, other):
            return self.expr == other.expr
    
        def to_dongbei(self):
            return f"绝对{self.expr.to_dongbei()}"
    
        def to_python(self):
            return f"abs({self.expr.to_python()})"
  8. Error Handling and Assertions

    master

    Assertions

    • 保准 CONDITION : If the condition is false, the program exits with an error message: 整叉劈了:该着 【NAME】....
    • 辟谣 CONDITION : Asserts that the condition must be false. If the condition is true, the program exits with an error.

    Manual Exit

    Use 整叉劈了:MESSAGE。 to print a custom error message and exit the program immediately.

  9. Testing patterns for dongbei features

    master

    When adding new features, follow the 'one test method per thing' rule. For a single feature like 歇会儿 (sleep), implement three types of tests:

    1. Tokenization Test: Verify the keyword is correctly identified by the parser.
    2. Parsing Test: Verify the Abstract Syntax Tree (AST) structure is correct (e.g., checking stmt.kind and stmt.value).
    3. Integration Test: Verify the full translation and execution cycle using translate_and_run() and mocking side effects (like time.sleep).
    # 1. Tokenization Test
    def test_tokenize_sleep_keyword(self):
        parser = DongbeiParser()
        tokens = parser.tokenize("歇会儿 一。", None)
        self.assertIn(Token(TK_KEYWORD, KW_SLEEP_STMT, None), tokens)
    
    # 2. Parsing Test
    def test_parse_sleep_stmt(self):
        stmt = parse_stmt_from_str("歇会儿 一。")
        self.assertEqual(stmt.kind, STMT_SLEEP)
        self.assertEqual(stmt.value, LiteralExpr(Token(TK_NUMBER_LITERAL, 1, None)))
    
    # 3. Integration Test
    from unittest.mock import patch
    
    def test_sleep_calls_time_sleep(self):
        with patch("time.sleep") as mock_sleep:
            translate_and_run("歇会儿 二。", None)
            mock_sleep.assert_called_once_with(2)
  10. Install the travis CLI for CI configuration

    master

    If you need to modify dongbei's CI settings, you may need to install the travis command-line tool. If you do not have superuser permissions on your machine, install it using the --user flag and add the installation path to your PATH environment variable.

    Example for Mac users:

    1. Install via gem: gem install travis -v 1.8.10 --no-rdoc --no-ri --user
    2. Add the path to ~/.profile: export PATH="$PATH:/Users/wangdada/.gem/ruby/2.3.0/bin" (replace wangdada with your actual username).
    gem install travis -v 1.8.10 --no-rdoc --no-ri --user
  11. Define and Call Functions (套路)

    master

    Functions (referred to as 套路) are defined using a specific structure:

    1. Define the name.
    2. Use 咋整 to start the function body.
    3. Use 整完了 to end the function body.

    To call a function, use the keyword followed by the function name. Functions can accept parameters inside parentheses () and can be recursive.