Official Guide & Reference

DJPROCODE

The Complete Developer's Reference Handbook
First Edition — 2026
DJPROCODE Cover Image
Written by Debojit Das
"This language was built not to copy the world, but to change it.
For every developer who dared to think differently —
who saw code not as a tool, but as a language of creation.

This book is for you."
— Debojit Das

Table of Contents

Part I

INTRODUCTION

An overview of the programming language designed for the next era of development.
Chapter 1

Introduction to DJPROCODE

DJPROCODE is a next-generation programming language engineered to bridge the gap between human readability, compiler performance, and artificial intelligence integration. In an era dominated by high-level languages like Python and low-level systems like C++, developers often face a trade-off between writing speed and execution efficiency. DJPROCODE is designed to provide an expressive, clean syntax that is easy for humans to read and write, while translating into highly optimized Virtual Machine bytecode that runs inside the DJVM (DJ Virtual Machine). One of the key design philosophies of DJPROCODE is structured minimalism. The language does not rely on braces or complex indentation rules. Instead, it utilizes clean keyword boundaries like start and stop to define execution blocks. This guarantees code predictability and prevents common errors like indentation misalignment. Additionally, DJPROCODE features native support for type checking, constants, and built-in standard libraries, making it a robust language for building software, scripting, and automation. Historically, languages were built with CPU instruction matching in mind. Today, they must be built with AI code generation, human developers, and cross-platform runtime environments in mind. DJPROCODE achieves this by choosing english-like words for arithmetic and comparisons, which aligns closely with how we think about algorithms logically.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Explain why DJPROCODE uses keywords like 'start' and 'stop' instead of curly braces.
  2. What is the role of the DJVM in executing DJPROCODE programs?
Chapter 2

History & Philosophy

DJPROCODE was created in 2026 by Debojit Das as a research project to explore human-centric language design. Over decades, programming languages have accumulated historical baggage, complex syntax specifications, and visual noise. The objective of DJPROCODE was to strip away all visual clutter—no semi-colons, no parentheses for control flow, no curly braces, and no cryptic mathematical symbols like != or &&. Instead, DJPROCODE replaces them with clean English keywords like notsame and both. The core tenets of DJPROCODE are: 1. Readability is first: Code should read like structured logic. If a non-programmer can understand the flow of the script, the language has succeeded. 2. Portability: Write once, run anywhere. By compiling source code into a custom, compact bytecode format, DJPROCODE files run instantly on any machine that hosts the DJVM. 3. Native Integration: Out-of-the-box support for advanced packages including graphics, math, and AI capabilities. The design of DJPROCODE draws inspiration from Python's clean structure, Pascal's explicit boundaries, and the robust virtual machine model of Java. The result is a language that feels both familiar and refreshingly simple, allowing developers to focus on architectural logic rather than syntax details.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Summarize the three core tenets of DJPROCODE.
  2. How does English-like operator naming benefit beginner programmers?
Chapter 3

Installing DJPROCODE

Getting started with DJPROCODE requires installing the DJPROCODE SDK. The SDK comes with the compiler toolchain, the DJVM interpreter, and the DJStudio interactive environment. The platform is fully cross-platform and runs natively on Windows, macOS, and Linux. Installation Steps: 1. Download the installer bundle from the official release page. 2. Extract the archive into a directory on your system, such as E:\DJPROCODE on Windows or /usr/local/djprocode on Unix-like operating systems. 3. Add the bin directory within the SDK path to your system's PATH environment variable. This allows running the compiler from any terminal using the command djprocode. 4. Verify the installation by running djprocode --version in your terminal. You should see version details like 'DJPROCODE v2.0 (DJVM)' printed to standard output. Additionally, the SDK includes editor extensions for popular development environments, including Visual Studio Code and JetBrains IDEs. These extensions provide syntax highlighting, code linting, and direct debugging hooks, enabling a premium development experience.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Walk through the steps to add the DJPROCODE bin directory to the Windows PATH.
  2. What command is used to verify that the compiler is installed correctly?
Chapter 4

Your First Program

Now that the environment is set up, let's write our first program. In DJPROCODE, every program is contained within a global entry block that begins with the keyword start and ends with stop. Inside this block, we write instructions that are executed sequentially by the Virtual Machine. To output text to the screen, we use the display keyword followed by a string literal. String literals are enclosed in double quotes. Comments are written starting with two forward slashes (//) and are ignored by the compiler, allowing developers to annotate their code for future reference. To run this code, write it into a text file named hello.djpc, and then run it in your terminal: djprocode hello.djpc The compiler will compile the file to bytecode, run it via the VM, and you will see 'Hello, World!' printed on the screen. Let's see the code and compile traces.

DJPROCODE Source Implementation

snippet_ch4.djpc
start
    // Print a welcome message
    display "Hello, World!"
stop

Python Equivalency Code

snippet_ch4.py
# Print a welcome message
print("Hello, World!")

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'display'3
2STRING'Hello, World!'3
3KEYWORD'stop'4
4EOFNone4

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
└── stmt: DisplayNode
    └── expr: LiteralNode
        ├── value: 'Hello, World!'
        └── type: 'word'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__'Hello, World!'
1DISPLAYNone

Review Exercises

  1. Create a program that prints your name and your city on two separate lines.
  2. Add a comment explaining what the program does.
Part II

CORE LANGUAGE FUNDAMENTALS

An in-depth look at blocks, indentation, comments, and keyword rules.
Chapter 5

Program Structure

The structure of a DJPROCODE program is designed to be highly structured and uniform. Unlike languages like C++, Java, or JavaScript that use curly braces {} to group statements, or Python that uses strict tab/space indentation, DJPROCODE uses block keywords. An execution block always has an opening keyword (like start, check, loop, create) and is closed by the keyword stop. This explicit boundaries structure provides major advantages: 1. Compiler safety: The parser knows exactly where a statement block ends, making parser error recovery extremely reliable. 2. Indentation freedom: While it is highly recommended to indent statements inside blocks for readability, it is not syntax-critical, unlike Python. Your program will compile and run correctly even if it is written without indents. 3. Clean look: The elimination of braces and semi-colons reduces visual noise, allowing the developer's eyes to focus on actual logic. Every statement in DJPROCODE is written on a new line. Semicolons are not used. You can write inline comments anywhere using //, which helps document variable purposes and complex flows.

DJPROCODE Source Implementation

snippet_ch5.djpc
start
    display "This is the start"
    display "Doing some work..."
stop

Python Equivalency Code

snippet_ch5.py
print("This is the start")
print("Doing some work...")

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'display'2
2STRING'This is the start'2
3KEYWORD'display'3
4STRING'Doing some work...'3
5KEYWORD'stop'4
6EOFNone4

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: DisplayNode
│   └── expr: LiteralNode
│       ├── value: 'This is the start'
│       └── type: 'word'
└── stmt: DisplayNode
    └── expr: LiteralNode
        ├── value: 'Doing some work...'
        └── type: 'word'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__'This is the start'
1DISPLAYNone
2__firstlineno__'Doing some work...'
3DISPLAYNone

Review Exercises

  1. Write a program that contains nested blocks using the check statement and verify they all terminate with stop.
  2. What happens if you run a script that lacks the stop keyword for start?
Chapter 6

Data Types

DJPROCODE is a typed language that supports six primitive and collection data types. Understanding these types is essential for managing memory and data transformations: 1. number: Represents integer values (positive, negative, or zero). Examples: 42, -10, 0. 2. point: Represents floating-point decimal numbers. Examples: 3.14159, -0.001, 100.0. 3. word: Represents textual data (strings). String literals are enclosed in double quotes. Example: "DJPROCODE". 4. logic: Represents boolean truth values. It has two literals: yes (true) and no (false). 5. group: Represents lists or arrays of values. These are indexed collections. Example: [1, 2, 3]. 6. nothing: Represents the null/empty type. It has a single literal: nothing. When declaring variables, you can explicitly define their type. This ensures that the virtual machine checks values and prevents illegal operations, such as adding a word to a number without explicit conversion.

DJPROCODE Source Implementation

snippet_ch6.djpc
start
    store x as number = 42
    store y as point = 3.14
    store s as word = "Hello"
    store b as logic = yes
    store g as group = [1, 2, 3]
    store n as nothing = nothing
stop

Python Equivalency Code

snippet_ch6.py
x: int = 42
y: float = 3.14
s: str = "Hello"
b: bool = True
g: list = [1, 2, 3]
n: None = None

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'2
2IDENTIFIER'x'2
3KEYWORD'as'2
4KEYWORD'number'2
5ASSIGNNone2
6NUMBER422
7KEYWORD'store'3
8IDENTIFIER'y'3
9KEYWORD'as'3
10KEYWORD'point'3
11ASSIGNNone3
12POINT3.143
13KEYWORD'store'4
14IDENTIFIER's'4
15KEYWORD'as'4
16KEYWORD'word'4
17ASSIGNNone4
18STRING'Hello'4
19KEYWORD'store'5
20IDENTIFIER'b'5
21KEYWORD'as'5
22KEYWORD'logic'5
23ASSIGNNone5
24KEYWORD'yes'5
25KEYWORD'store'6
26IDENTIFIER'g'6
27KEYWORD'as'6
28KEYWORD'group'6
29ASSIGNNone6
30LBRACKETNone6
31NUMBER16
32COMMANone6
33NUMBER26
34COMMANone6
35NUMBER36
36RBRACKETNone6
37KEYWORD'store'7
38IDENTIFIER'n'7
39KEYWORD'as'7
40KEYWORD'nothing'7
41ASSIGNNone7
42KEYWORD'nothing'7
43KEYWORD'stop'8
44EOFNone8

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: StoreNode
│   ├── expr: LiteralNode
│   │   ├── value: 42
│   │   └── type: 'number'
│   └── datatype: 'number'
├── stmt: StoreNode
│   ├── expr: LiteralNode
│   │   ├── value: 3.14
│   │   └── type: 'point'
│   └── datatype: 'point'
├── stmt: StoreNode
│   ├── expr: LiteralNode
│   │   ├── value: 'Hello'
│   │   └── type: 'word'
│   └── datatype: 'word'
├── stmt: StoreNode
│   ├── expr: LiteralNode
│   │   ├── value: True
│   │   └── type: 'logic'
│   └── datatype: 'logic'
├── stmt: StoreNode
│   ├── expr: LiteralNode
│   │   ├── value: [, , ]
│   │   └── type: 'group'
│   └── datatype: 'group'
└── stmt: StoreNode
    ├── expr: LiteralNode
    │   └── type: 'nothing'
    └── datatype: 'nothing'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__42
1STORE_VAR('x', 'number')
2__firstlineno__3.14
3STORE_VAR('y', 'point')
4__firstlineno__'Hello'
5STORE_VAR('s', 'word')
6__firstlineno__True
7STORE_VAR('b', 'logic')
8__firstlineno__1
9__firstlineno__2
10__firstlineno__3
11BUILD_LIST3
12STORE_VAR('g', 'group')
13__firstlineno__None
14STORE_VAR('n', 'nothing')

Review Exercises

  1. Declare a variable of type logic and initialize it to yes.
  2. Create a list containing three points, representing coordinate coordinates.
Chapter 7

Variables

Variables are names that bind to values, allowing programs to store and mutate state during execution. In DJPROCODE, variables are declared using the store keyword. Variables can be declared with a strict type or implicitly typed based on the value assigned to them. Syntax: store as = (Strict type declaration) store = (Implicit type declaration) Once a variable is declared, you can update its value using the same store keyword followed by the new value. The compiler distinguishes declaration from reassignment by scanning the scope. If the variable name already exists in the environment, it performs an update. Variable names must start with a letter or underscore, followed by letters, numbers, or underscores. They are case-sensitive, meaning myVar and myvar are treated as two separate variables.

DJPROCODE Source Implementation

snippet_ch7.djpc
start
    store score as number = 10
    display score
    store score = 25
    display score
stop

Python Equivalency Code

snippet_ch7.py
score: int = 10
print(score)
score = 25
print(score)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'2
2IDENTIFIER'score'2
3KEYWORD'as'2
4KEYWORD'number'2
5ASSIGNNone2
6NUMBER102
7KEYWORD'display'3
8IDENTIFIER'score'3
9KEYWORD'store'4
10IDENTIFIER'score'4
11ASSIGNNone4
12NUMBER254
13KEYWORD'display'5
14IDENTIFIER'score'5
15KEYWORD'stop'6
16EOFNone6

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: StoreNode
│   ├── expr: LiteralNode
│   │   ├── value: 10
│   │   └── type: 'number'
│   └── datatype: 'number'
├── stmt: DisplayNode
│   └── expr: VarAccessNode
│       └── var_name: 'score'
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 25
│       └── type: 'number'
└── stmt: DisplayNode
    └── expr: VarAccessNode
        └── var_name: 'score'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__10
1STORE_VAR('score', 'number')
2MOVE_VAR'score'
3DISPLAYNone
4__firstlineno__25
5STORE_VAR('score', None)
6MOVE_VAR'score'
7DISPLAYNone

Review Exercises

  1. Declare a typed word variable, display it, then update its value and display it again.
  2. Write a script that swaps the values of two variables.
Chapter 8

Constants (Fixed Variables)

In software development, some values should never change during program execution. Examples include mathematical constants like Pi, configuration settings, or system keys. In DJPROCODE, these values are declared as constants using the fixed keyword instead of store. Syntax: fixed as = When the compiler encounters a fixed declaration, it marks the variable name as immutable. Any subsequent attempt to assign a new value to this constant will cause the compiler to raise a compile-time warning or the VM to raise a runtime exception. Using constants has multiple benefits: 1. Safety: Prevents accidental modifications to critical data. 2. Readability: Signifies to other developers that this value is static and constant. 3. Optimization: The compiler can optimize access paths for read-only values.

DJPROCODE Source Implementation

snippet_ch8.djpc
start
    fixed PI as point = 3.14159
    display PI
stop

Python Equivalency Code

snippet_ch8.py
PI = 3.14159 # Python does not support true constants
print(PI)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'fixed'2
2IDENTIFIER'PI'2
3KEYWORD'as'2
4KEYWORD'point'2
5ASSIGNNone2
6POINT3.141592
7KEYWORD'display'3
8IDENTIFIER'PI'3
9KEYWORD'stop'4
10EOFNone4

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: StoreNode
│   ├── expr: LiteralNode
│   │   ├── value: 3.14159
│   │   └── type: 'point'
│   └── datatype: 'point'
└── stmt: DisplayNode
    └── expr: VarAccessNode
        └── var_name: 'PI'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__3.14159
1STORE_VAR('PI', 'point')
2MOVE_VAR'PI'
3DISPLAYNone

Review Exercises

  1. Declare a fixed variable for the speed of light (299792458) as a number.
  2. Test what error is printed if you attempt to reassign this constant.
Chapter 9

Operators

Operators are special keywords or symbols used to perform operations on variables and values. DJPROCODE deviates from C-style syntax by replacing mathematical symbols with clear, English keywords, which makes code read like logical statements. Categories of Operators: 1. Arithmetic: - plus: Addition or string concatenation. - minus: Subtraction. - into: Multiplication. - by: Division. - remain: Modulo (remainder of division). 2. Comparison: - same: Equality check (==). - notsame: Inequality check (!=). - big: Greater than (>). - small: Less than (<). - bigsame: Greater than or equal (>=). - smallsame: Less than or equal (<=). 3. Logical: - both: Logical AND (&&). - either: Logical OR (||). - reverse: Logical NOT (!). This syntax ensures that operations are easy to read and understand, even for non-technical users.

DJPROCODE Source Implementation

snippet_ch9.djpc
start
    store x = 10 plus 5
    store y = x into 2
    store b = y same 30
    display b
stop

Python Equivalency Code

snippet_ch9.py
x = 10 + 5
y = x * 2
b = y == 30
print(b)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'2
2IDENTIFIER'x'2
3ASSIGNNone2
4NUMBER102
5KEYWORD'plus'2
6NUMBER52
7KEYWORD'store'3
8IDENTIFIER'y'3
9ASSIGNNone3
10IDENTIFIER'x'3
11KEYWORD'into'3
12NUMBER23
13KEYWORD'store'4
14IDENTIFIER'b'4
15ASSIGNNone4
16IDENTIFIER'y'4
17KEYWORD'same'4
18NUMBER304
19KEYWORD'display'5
20IDENTIFIER'b'5
21KEYWORD'stop'6
22EOFNone6

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: AssignNode
│   └── expr: BinOpNode
│       ├── left: LiteralNode
│       │   ├── value: 10
│       │   └── type: 'number'
│       └── right: LiteralNode
│           ├── value: 5
│           └── type: 'number'
├── stmt: AssignNode
│   └── expr: BinOpNode
│       ├── left: VarAccessNode
│       │   └── var_name: 'x'
│       └── right: LiteralNode
│           ├── value: 2
│           └── type: 'number'
├── stmt: AssignNode
│   └── expr: BinOpNode
│       ├── left: VarAccessNode
│       │   └── var_name: 'y'
│       └── right: LiteralNode
│           ├── value: 30
│           └── type: 'number'
└── stmt: DisplayNode
    └── expr: VarAccessNode
        └── var_name: 'b'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__10
1__firstlineno__5
2BINARY_OP'plus'
3STORE_VAR('x', None)
4MOVE_VAR'x'
5__firstlineno__2
6BINARY_OP'into'
7STORE_VAR('y', None)
8MOVE_VAR'y'
9__firstlineno__30
10BINARY_OP'same'
11STORE_VAR('b', None)
12MOVE_VAR'b'
13DISPLAYNone

Review Exercises

  1. Write an expression that checks if a number is even by using the remain keyword.
  2. Combine two comparison expressions using the both operator.
Chapter 10

User Input

Interactive programs require user inputs. In DJPROCODE, reading input from the user is handled by the take keyword. The input value is read from standard input as a string (word) and stored in a designated variable. Syntax: take "Enter your message: " in (Input with prompt) take (Input without prompt) The input read by take is always captured as a string (type word). If you need to perform arithmetic operations on the user input, you must convert it into a numeric type using standard library functions like makeNumber(x) or makePoint(x). Let's see an example where we prompt the user for their name and print a personalized greeting.

DJPROCODE Source Implementation

snippet_ch10.djpc
start
    take "What is your name?" in userName
    display "Hello " plus userName
stop

Python Equivalency Code

snippet_ch10.py
userName = input("What is your name? ")
print("Hello " + userName)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'take'2
2STRING'What is your name?'2
3KEYWORD'in'2
4IDENTIFIER'userName'2
5KEYWORD'display'3
6STRING'Hello '3
7KEYWORD'plus'3
8IDENTIFIER'userName'3
9KEYWORD'stop'4
10EOFNone4

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: TakeNode
│   └── var_name: 'userName'
└── stmt: DisplayNode
    └── expr: BinOpNode
        ├── left: LiteralNode
        │   ├── value: 'Hello '
        │   └── type: 'word'
        └── right: VarAccessNode
            └── var_name: 'userName'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__'What is your name?'
1TAKE_PROMPT'userName'
2__firstlineno__'Hello '
3MOVE_VAR'userName'
4BINARY_OP'plus'
5DISPLAYNone

Review Exercises

  1. Prompt the user to enter their age, convert it to a number, and display the age next year.
  2. Write a script that takes two string inputs and prints them joined together.
Chapter 11

Output / Display

Printing text and variable states to standard output is one of the most fundamental operations in programming. In DJPROCODE, this is performed by the display keyword. Unlike most languages that require parenthesis and function wrappers, display is an built-in statement. Syntax: display The expression can be a string literal, a variable, a numeric value, or a complex expression combining variables, mathematical operations, and function calls. String Concatenation: In DJPROCODE, strings are concatenated using the plus operator. When a string is added to a non-string value (like a number), the VM automatically converts the non-string value to a string representation, allowing easy prints. Escaping Characters: You can use standard escape sequences inside strings, such as \n for newlines and \t for tab alignments. These are expanded dynamically by the VM when displaying the output.

DJPROCODE Source Implementation

snippet_ch11.djpc
start
    store age = 21
    display "Name:\tDebojit\nAge:\t" plus age
stop

Python Equivalency Code

snippet_ch11.py
age = 21
print("Name:\tDebojit\nAge:\t" + str(age))

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'2
2IDENTIFIER'age'2
3ASSIGNNone2
4NUMBER212
5KEYWORD'display'3
6STRING'Name:\tDebojit\nAge:\t'3
7KEYWORD'plus'3
8IDENTIFIER'age'3
9KEYWORD'stop'4
10EOFNone4

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 21
│       └── type: 'number'
└── stmt: DisplayNode
    └── expr: BinOpNode
        ├── left: LiteralNode
        │   ├── value: 'Name:\tDebojit\nAge:\t'
        │   └── type: 'word'
        └── right: VarAccessNode
            └── var_name: 'age'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__21
1STORE_VAR('age', None)
2__firstlineno__'Name:\tDebojit\nAge:\t'
3MOVE_VAR'age'
4BINARY_OP'plus'
5DISPLAYNone

Review Exercises

  1. Create a program that displays a 3x3 grid of stars using newline characters.
  2. Print the result of the expression 5 plus 10 directly inside a display statement.
Chapter 12

Comments

Comments are annotations written inside source code to explain what the program is doing. They are completely ignored by the compiler and do not affect program execution or compile times. In DJPROCODE, comments are initiated using double forward slashes (//). Types of Comment Usage: 1. Line comments: The comment occupies a full line. // Calculate final cost with tax store finalCost = total plus tax 2. Inline comments: The comment is written at the end of an active line of code. store tax = 18 // GST percentage Writing clear comments is a hallmark of professional software engineering. It helps you remember how your code works when you return to it months later, and helps other team members read and collaborate on your codebase.

DJPROCODE Source Implementation

snippet_ch12.djpc
start
        // This program demonstrates comments
        store x = 5 // Initial coordinate
        display x
stop

Python Equivalency Code

snippet_ch12.py
# This program demonstrates comments
x = 5 # Initial coordinate
print(x)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'3
2IDENTIFIER'x'3
3ASSIGNNone3
4NUMBER53
5KEYWORD'display'4
6IDENTIFIER'x'4
7KEYWORD'stop'5
8EOFNone5

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 5
│       └── type: 'number'
└── stmt: DisplayNode
    └── expr: VarAccessNode
        └── var_name: 'x'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__5
1STORE_VAR('x', None)
2MOVE_VAR'x'
3DISPLAYNone

Review Exercises

  1. Write a script that contains a comment on every line explaining the statement's purpose.
  2. What happens if you write a comment inside a string literal, e.g., 'display "// hello"'?
Part I

CONTROL FLOW

Making decisions and branch selections in code using check blocks.
Chapter 13

Conditional Statements (check / otherwise)

Control flow defines the path of execution in a program. The most common way to branch execution paths is using conditional statements. In DJPROCODE, conditional branching is handled by the check and otherwise keywords, representing 'if' and 'else' in legacy languages. Syntax: check // code block to run if condition is true stop The condition is an expression that evaluates to a boolean (type logic), either yes or no. Adding Else Blocks: To define code that executes if the condition is false, append the otherwise keyword: check // code for yes otherwise // code for no stop Notice that the entire conditional block is terminated by a single stop keyword at the end, keeping the structure clean and bounded.

DJPROCODE Source Implementation

snippet_ch13.djpc
start
    store score = 85
    check score big 50
        display "Pass"
    otherwise
        display "Fail"
    stop
stop

Python Equivalency Code

snippet_ch13.py
score = 85
if score > 50:
    print("Pass")
else:
    print("Fail")

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'2
2IDENTIFIER'score'2
3ASSIGNNone2
4NUMBER852
5KEYWORD'check'3
6IDENTIFIER'score'3
7KEYWORD'big'3
8NUMBER503
9KEYWORD'display'4
10STRING'Pass'4
11KEYWORD'otherwise'5
12KEYWORD'display'6
13STRING'Fail'6
14KEYWORD'stop'7
15KEYWORD'stop'8
16EOFNone8

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 85
│       └── type: 'number'
└── stmt: CheckNode
    ├── case_0_cond: BinOpNode
    │   ├── left: VarAccessNode
    │   │   └── var_name: 'score'
    │   └── right: LiteralNode
    │       ├── value: 50
    │       └── type: 'number'
    ├── case_0_stmt_0: DisplayNode
    │   └── expr: LiteralNode
    │       ├── value: 'Pass'
    │       └── type: 'word'
    └── otherwise_stmt_0: DisplayNode
        └── expr: LiteralNode
            ├── value: 'Fail'
            └── type: 'word'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__85
1STORE_VAR('score', None)
2MOVE_VAR'score'
3__firstlineno__50
4BINARY_OP'big'
5JUMP_IF_FALSE9
6__firstlineno__'Pass'
7DISPLAYNone
8JUMP11
9__firstlineno__'Fail'
10DISPLAYNone

Review Exercises

  1. Write a program that takes a number and prints 'Positive' or 'Negative' using check/otherwise.
  2. Explain how the stop keyword resolves ambiguity in nested checks.
Chapter 14

Switch-Case (choose / case)

When a program needs to branch into multiple execution paths based on the discrete values of a single variable, chaining many otherwise check blocks can make code hard to read and compile. In DJPROCODE, this is resolved by the choose and case keywords, which act as switch-case blocks. Syntax: choose case // code stop case // code stop default // fallback code stop stop Each case block has its own internal logic that is bounded by its own stop keyword. The entire choose statement is closed by a final stop keyword. This structure avoids the common fall-through bugs found in languages like C/C++/Java, because each case is treated as an independent block. If a case matches, its code runs, and execution automatically exits the choose statement, with no manual break statements required.

DJPROCODE Source Implementation

snippet_ch14.djpc
start
    store code = 2
    choose code
        case 1
            display "One"
        stop
        case 2
            display "Two"
        stop
        default
            display "Other"
        stop
    stop
stop

Python Equivalency Code

snippet_ch14.py
code = 2
match code: # Python 3.10+ match syntax
    case 1: print("One")
    case 2: print("Two")
    case _: print("Other")

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'2
2IDENTIFIER'code'2
3ASSIGNNone2
4NUMBER22
5KEYWORD'choose'3
6IDENTIFIER'code'3
7KEYWORD'case'4
8NUMBER14
9KEYWORD'display'5
10STRING'One'5
11KEYWORD'stop'6
12KEYWORD'case'7
13NUMBER27
14KEYWORD'display'8
15STRING'Two'8
16KEYWORD'stop'9
17KEYWORD'default'10
18KEYWORD'display'11
19STRING'Other'11
20KEYWORD'stop'12
21KEYWORD'stop'13
22KEYWORD'stop'14
23EOFNone14

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 2
│       └── type: 'number'
└── stmt: ChooseNode
    ├── case_0: (, [], False)
    ├── case_1: (, [], False)
    ├── default_stmt_0: DisplayNode
    │   └── expr: LiteralNode
    │       ├── value: 'Other'
    │       └── type: 'word'
    └── var_name: 'code'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__2
1STORE_VAR('code', None)
2LOAD_VAR'code'
3DUPNone
4__firstlineno__1
5BINARY_OP'same'
6JUMP_IF_FALSE11
7POPNone
8__firstlineno__'One'
9DISPLAYNone
10JUMP22
11DUPNone
12__firstlineno__2
13BINARY_OP'same'
14JUMP_IF_FALSE19
15POPNone
16__firstlineno__'Two'
17DISPLAYNone
18JUMP22
19POPNone
20__firstlineno__'Other'
21DISPLAYNone

Review Exercises

  1. Create a traffic light simulator using choose/case that translates 'R', 'Y', and 'G' into their action meanings.
  2. What happens if no case matches and there is no default block?
Chapter 15

Loops — Repeat N Times (loop)

Repetition is a core tool in programming. Often, you just need to repeat a sequence of instructions a specific number of times. Instead of writing complex loop indices and conditions, DJPROCODE offers a simple, dedicated keyword: loop. Syntax: loop // code to repeat stop The count expression must evaluate to an integer (type number). The VM reads this count, initializes an internal hidden counter, and repeats the execution block exactly N times. This simple loop syntax is perfect for operations like printing headers, drawing grids, repeating actions, or running fixed-iteration simulations. Under the hood, the compiler translates this into a highly optimized index register decrement structure.

DJPROCODE Source Implementation

snippet_ch15.djpc
start
    loop 3
        display "Hello Loop"
    stop
stop

Python Equivalency Code

snippet_ch15.py
for _ in range(3):
    print("Hello Loop")

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'loop'2
2NUMBER32
3KEYWORD'display'3
4STRING'Hello Loop'3
5KEYWORD'stop'4
6KEYWORD'stop'5
7EOFNone5

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
└── stmt: LoopNode
    └── stmt: DisplayNode
        └── expr: LiteralNode
            ├── value: 'Hello Loop'
            └── type: 'word'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__3
1STORE_VAR'__loop_counter__'
2LOAD_VAR'__loop_counter__'
3__firstlineno__0
4BINARY_OP'big'
5JUMP_IF_FALSE13
6__firstlineno__'Hello Loop'
7DISPLAYNone
8LOAD_VAR'__loop_counter__'
9__firstlineno__1
10BINARY_OP'minus'
11STORE_VAR'__loop_counter__'
12JUMP2

Review Exercises

  1. Write a program that prints 'Loading...' 5 times using a loop.
  2. Nest a loop inside another loop to print a 2D coordinate grid of symbols.
Chapter 16

Loops — Counted Range (count from to)

When iterating, you often need access to the current loop counter index (for example, printing a list index or executing calculations on index steps). In DJPROCODE, this is handled by the count loop. Syntax: count from to // code stop The loop index variable is created automatically in the loop environment. The loop starts by assigning the evaluated value of start to the index variable, runs the block, increments (or decrements) the variable, and checks if it has crossed the end limit. Reverse Counting: DJPROCODE supports reverse counting natively. If the start expression evaluates to a value greater than the end expression, the compiler automatically detects this and decrements the index variable by 1 on each step, rather than incrementing. This eliminates the need for manual negative step declarations.

DJPROCODE Source Implementation

snippet_ch16.djpc
start
    count i from 1 to 4
        display i
    stop
stop

Python Equivalency Code

snippet_ch16.py
for i in range(1, 5):
    print(i)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'count'2
2IDENTIFIER'i'2
3KEYWORD'from'2
4NUMBER12
5KEYWORD'to'2
6NUMBER42
7KEYWORD'display'3
8IDENTIFIER'i'3
9KEYWORD'stop'4
10KEYWORD'stop'5
11EOFNone5

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
└── stmt: CountLoopNode
    ├── stmt: DisplayNode
    │   └── expr: VarAccessNode
    │       └── var_name: 'i'
    └── var_name: 'i'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__1
1STORE_VAR'i'
2LOAD_VAR'i'
3__firstlineno__4
4BINARY_OP'smallsame'
5JUMP_IF_FALSE13
6MOVE_VAR'i'
7DISPLAYNone
8LOAD_VAR'i'
9__firstlineno__1
10BINARY_OP'plus'
11STORE_VAR'i'
12JUMP2

Review Exercises

  1. Write a program that counts backwards from 10 to 1 and displays each number.
  2. Calculate the sum of all numbers from 1 to 100 using a count loop.
Chapter 17

Loops — Condition-Based (until)

In many algorithms, the number of repetitions is unknown beforehand. Instead, the loop should repeat as long as a certain logical condition holds. While legacy languages use a 'while' loop that repeats *while* a condition is true, DJPROCODE uses the until loop. Syntax: until // code to run stop The until loop is a negative conditional loop. It evaluates the condition before each iteration. If the condition is false (no), it executes the block. The loop continues to run **until** the condition evaluates to true (yes). This alignment matches closely with real-world instructions: "Keep working until the task is complete". If the condition is true at the very beginning, the loop body is skipped entirely.

DJPROCODE Source Implementation

snippet_ch17.djpc
start
    store x = 1
    until x big 3
        display x
        store x = x plus 1
    stop
stop

Python Equivalency Code

snippet_ch17.py
x = 1
while not (x > 3):
    print(x)
    x = x + 1

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'2
2IDENTIFIER'x'2
3ASSIGNNone2
4NUMBER12
5KEYWORD'until'3
6IDENTIFIER'x'3
7KEYWORD'big'3
8NUMBER33
9KEYWORD'display'4
10IDENTIFIER'x'4
11KEYWORD'store'5
12IDENTIFIER'x'5
13ASSIGNNone5
14IDENTIFIER'x'5
15KEYWORD'plus'5
16NUMBER15
17KEYWORD'stop'6
18KEYWORD'stop'7
19EOFNone7

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 1
│       └── type: 'number'
└── stmt: UntilNode
    ├── stmt: DisplayNode
    │   └── expr: VarAccessNode
    │       └── var_name: 'x'
    └── stmt: AssignNode
        └── expr: BinOpNode
            ├── left: VarAccessNode
            │   └── var_name: 'x'
            └── right: LiteralNode
                ├── value: 1
                └── type: 'number'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__1
1STORE_VAR('x', None)
2MOVE_VAR'x'
3__firstlineno__3
4BINARY_OP'big'
5JUMP_IF_FALSE13
6MOVE_VAR'x'
7DISPLAYNone
8MOVE_VAR'x'
9__firstlineno__1
10BINARY_OP'plus'
11STORE_VAR('x', None)
12JUMP2

Review Exercises

  1. Prompt the user to enter their passcode inside an until loop that continues until they enter the correct word.
  2. Implement a simple counter that doubles its value until it exceeds 100.
Chapter 18

Loop Control (exit / skip)

Sometimes, you need to alter loop execution paths from inside the loop body. For instance, you might want to terminate the loop early if a specific condition is met, or skip the remainder of the current iteration and proceed to the next step. DJPROCODE provides two loop control statements: 1. exit: Immediately terminates the innermost loop. Program control jumps to the first statement following the loop's closing stop. 2. skip: Skips the remaining statements in the current iteration and jumps directly to the step/condition evaluation phase of the loop. These statements are equivalent to 'break' and 'continue' in legacy languages. Using them carefully enables cleaner, more readable loop logic by avoiding deeply nested check blocks.

DJPROCODE Source Implementation

snippet_ch18.djpc
start
    count i from 1 to 5
        check i same 3
            exit
        stop
        display i
    stop
stop

Python Equivalency Code

snippet_ch18.py
for i in range(1, 6):
    if i == 3:
        break
    print(i)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'count'2
2IDENTIFIER'i'2
3KEYWORD'from'2
4NUMBER12
5KEYWORD'to'2
6NUMBER52
7KEYWORD'check'3
8IDENTIFIER'i'3
9KEYWORD'same'3
10NUMBER33
11KEYWORD'exit'4
12KEYWORD'stop'5
13KEYWORD'display'6
14IDENTIFIER'i'6
15KEYWORD'stop'7
16KEYWORD'stop'8
17EOFNone8

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
└── stmt: CountLoopNode
    ├── stmt: CheckNode
    │   ├── case_0_cond: BinOpNode
    │   │   ├── left: VarAccessNode
    │   │   │   └── var_name: 'i'
    │   │   └── right: LiteralNode
    │   │       ├── value: 3
    │   │       └── type: 'number'
    │   └── case_0_stmt_0: BreakNode
    ├── stmt: DisplayNode
    │   └── expr: VarAccessNode
    │       └── var_name: 'i'
    └── var_name: 'i'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__1
1STORE_VAR'i'
2LOAD_VAR'i'
3__firstlineno__5
4BINARY_OP'smallsame'
5JUMP_IF_FALSE19
6MOVE_VAR'i'
7__firstlineno__3
8BINARY_OP'same'
9JUMP_IF_FALSE12
10JUMP19
11JUMP12
12MOVE_VAR'i'
13DISPLAYNone
14LOAD_VAR'i'
15__firstlineno__1
16BINARY_OP'plus'
17STORE_VAR'i'
18JUMP2

Review Exercises

  1. Write a count loop from 1 to 10 that skips printing even numbers using the skip keyword.
  2. Write an until loop that reads input and exits immediately if the user types 'exit'.
Part I

FUNCTIONS

Declaring reusable blocks of code with custom parameters using create.
Chapter 19

Defining Functions (create)

Functions are the foundation of clean, modular code. By grouping statements into a named unit, developers can reuse logic across multiple parts of an application, reducing repetition and easing maintenance. In DJPROCODE, functions are defined using the create keyword. Syntax: create () // body statements stop The parameters are a comma-separated list of variables that the function expects to receive when it is called. If the function doesn't require parameters, write empty parentheses (). Inside the function body, you can write any valid DJPROCODE statements. Variable scopes are managed locally; parameters and variables declared inside the function using store are local to that function and disappear when the function completes.

DJPROCODE Source Implementation

snippet_ch19.djpc
start
    create greetUser(name)
        display "Hello, " plus name
    stop
    
    open greetUser("Debojit")
stop

Python Equivalency Code

snippet_ch19.py
def greetUser(name):
    print("Hello, " + name)

greetUser("Debojit")

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'create'2
2IDENTIFIER'greetUser'2
3LPARENNone2
4IDENTIFIER'name'2
5RPARENNone2
6KEYWORD'display'3
7STRING'Hello, '3
8KEYWORD'plus'3
9IDENTIFIER'name'3
10KEYWORD'stop'4
11KEYWORD'open'6
12IDENTIFIER'greetUser'6
13LPARENNone6
14STRING'Debojit'6
15RPARENNone6
16KEYWORD'stop'7
17EOFNone7

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: CreateFunctionNode
│   ├── stmt: DisplayNode
│   │   └── expr: BinOpNode
│   │       ├── left: LiteralNode
│   │       │   ├── value: 'Hello, '
│   │       │   └── type: 'word'
│   │       └── right: VarAccessNode
│   │           └── var_name: 'name'
│   ├── func_name: 'greetUser'
│   └── params: [name]
└── stmt: OpenFunctionNode
    ├── func_name: 'greetUser'
    └── arg_0: LiteralNode
        ├── value: 'Debojit'
        └── type: 'word'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0MAKE_FUNCTION('greetUser', ['name'], )
1STORE_VAR'greetUser'
2LOAD_VAR'greetUser'
3__firstlineno__'Debojit'
4CALL_FUNCTION1

Review Exercises

  1. Define a function called 'printDouble' that takes a number and prints its value multiplied by 2.
  2. Explain the concept of local variable scope.
Chapter 20

Calling Functions (open)

Once a function has been defined, it can be executed. In DJPROCODE, function invocation is performed using the open keyword. Syntax: open () The arguments are expressions passed to the function parameters. The compiler evaluates these expressions and binds the results to the parameter names in the function's local execution frame. Naked Calls vs Expression Calls: You can call a function as a standalone statement: open logMessage("Success") Or you can use a function call within an expression (if the function returns a value): store result = open doubleValue(10) plus 5 The open keyword makes function calls highly explicit and visually distinct from variable accesses.

DJPROCODE Source Implementation

snippet_ch20.djpc
start
    create welcome()
        display "Welcome!"
    stop
    
    open welcome()
stop

Python Equivalency Code

snippet_ch20.py
def welcome():
    print("Welcome!")

welcome()

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'create'2
2IDENTIFIER'welcome'2
3LPARENNone2
4RPARENNone2
5KEYWORD'display'3
6STRING'Welcome!'3
7KEYWORD'stop'4
8KEYWORD'open'6
9IDENTIFIER'welcome'6
10LPARENNone6
11RPARENNone6
12KEYWORD'stop'7
13EOFNone7

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: CreateFunctionNode
│   ├── stmt: DisplayNode
│   │   └── expr: LiteralNode
│   │       ├── value: 'Welcome!'
│   │       └── type: 'word'
│   ├── func_name: 'welcome'
│   └── params: []
└── stmt: OpenFunctionNode
    └── func_name: 'welcome'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0MAKE_FUNCTION('welcome', [], )
1STORE_VAR'welcome'
2LOAD_VAR'welcome'
3CALL_FUNCTION0

Review Exercises

  1. Call the standard library function 'root' with the argument 64 and print the result.
  2. Create a function that prints a line, and call it three times.
Chapter 21

Return Values (send back)

Functions often act as data processors: they receive inputs, perform calculations, and return a result to the caller. In DJPROCODE, returning values from functions is handled by the send back statement. Syntax: send back When the VM hits a send back statement, it evaluates the expression, terminates the current function frame, pops it off the call stack, and pushes the return value onto the parent frame's stack. If a function completes execution without hitting a send back statement, it implicitly returns nothing. You can write multiple send back statements inside conditional blocks in a function, allowing early exits based on logical tests.

DJPROCODE Source Implementation

snippet_ch21.djpc
start
    create addNums(a, b)
        send back a plus b
    stop
    
    store sum = open addNums(5, 7)
    display sum
stop

Python Equivalency Code

snippet_ch21.py
def addNums(a, b):
    return a + b

sum = addNums(5, 7)
print(sum)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'create'2
2IDENTIFIER'addNums'2
3LPARENNone2
4IDENTIFIER'a'2
5COMMANone2
6IDENTIFIER'b'2
7RPARENNone2
8KEYWORD'send'3
9KEYWORD'back'3
10IDENTIFIER'a'3
11KEYWORD'plus'3
12IDENTIFIER'b'3
13KEYWORD'stop'4
14KEYWORD'store'6
15IDENTIFIER'sum'6
16ASSIGNNone6
17KEYWORD'open'6
18IDENTIFIER'addNums'6
19LPARENNone6
20NUMBER56
21COMMANone6
22NUMBER76
23RPARENNone6
24KEYWORD'display'7
25IDENTIFIER'sum'7
26KEYWORD'stop'8
27EOFNone8

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: CreateFunctionNode
│   ├── stmt: ReturnNode
│   │   └── expr: BinOpNode
│   │       ├── left: VarAccessNode
│   │       │   └── var_name: 'a'
│   │       └── right: VarAccessNode
│   │           └── var_name: 'b'
│   ├── func_name: 'addNums'
│   └── params: [a, b]
├── stmt: AssignNode
│   └── expr: OpenFunctionNode
│       ├── func_name: 'addNums'
│       ├── arg_0: LiteralNode
│       │   ├── value: 5
│       │   └── type: 'number'
│       └── arg_1: LiteralNode
│           ├── value: 7
│           └── type: 'number'
└── stmt: DisplayNode
    └── expr: VarAccessNode
        └── var_name: 'sum'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0MAKE_FUNCTION('addNums', ['a', 'b'], )
1STORE_VAR'addNums'
2LOAD_VAR'addNums'
3__firstlineno__5
4__firstlineno__7
5CALL_FUNCTION2
6STORE_VAR('sum', None)
7MOVE_VAR'sum'
8DISPLAYNone

Review Exercises

  1. Define a function 'maxVal' that takes two numbers and returns the larger one.
  2. What value is returned by a function that does not contain a send back statement?
Chapter 22

Nested Functions & Recursion

Recursion is a programming technique where a function calls itself to solve a smaller instance of the same problem. This is highly useful for algorithms involving tree structures, math progressions, or sorting. DJPROCODE fully supports recursive function calls. The DJVM maintains a frame stack where each recursive call pushes a new execution frame with its own local variables. When the base case is reached, the frames pop back in reverse order, passing return values up the stack. Nested Scopes: Functions can access variables defined in outer scopes (like the global environment). However, modifications to these outer variables require caution. Understanding how functions scope variables protects against unexpected mutations and makes code cleaner. Let's look at the classic mathematical calculation: the Factorial of a number, calculated recursively. Formula: \(n! = n \times (n-1)!\) with base case \(1! = 1\).

DJPROCODE Source Implementation

snippet_ch22.djpc
start
    create factorial(n)
        check n small 2
            send back 1
        stop
        send back n into open factorial(n minus 1)
    stop
    
    store res = open factorial(4)
    display res
stop

Python Equivalency Code

snippet_ch22.py
def factorial(n):
    if n < 2:
        return 1
    return n * factorial(n - 1)

res = factorial(4)
print(res)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'create'2
2IDENTIFIER'factorial'2
3LPARENNone2
4IDENTIFIER'n'2
5RPARENNone2
6KEYWORD'check'3
7IDENTIFIER'n'3
8KEYWORD'small'3
9NUMBER23
10KEYWORD'send'4
11KEYWORD'back'4
12NUMBER14
13KEYWORD'stop'5
14KEYWORD'send'6
15KEYWORD'back'6
16IDENTIFIER'n'6
17KEYWORD'into'6
18KEYWORD'open'6
19IDENTIFIER'factorial'6
20LPARENNone6
21IDENTIFIER'n'6
22KEYWORD'minus'6
23NUMBER16
24RPARENNone6
25KEYWORD'stop'7
26KEYWORD'store'9
27IDENTIFIER'res'9
28ASSIGNNone9
29KEYWORD'open'9
30IDENTIFIER'factorial'9
31LPARENNone9
32NUMBER49
33RPARENNone9
34KEYWORD'display'10
35IDENTIFIER'res'10
36KEYWORD'stop'11
37EOFNone11

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: CreateFunctionNode
│   ├── stmt: CheckNode
│   │   ├── case_0_cond: BinOpNode
│   │   │   ├── left: VarAccessNode
│   │   │   │   └── var_name: 'n'
│   │   │   └── right: LiteralNode
│   │   │       ├── value: 2
│   │   │       └── type: 'number'
│   │   └── case_0_stmt_0: ReturnNode
│   │       └── expr: LiteralNode
│   │           ├── value: 1
│   │           └── type: 'number'
│   ├── stmt: ReturnNode
│   │   └── expr: BinOpNode
│   │       ├── left: VarAccessNode
│   │       │   └── var_name: 'n'
│   │       └── right: OpenFunctionNode
│   │           ├── func_name: 'factorial'
│   │           └── arg_0: BinOpNode
│   │               ├── left: VarAccessNode
│   │               │   └── var_name: 'n'
│   │               └── right: LiteralNode
│   │                   ├── value: 1
│   │                   └── type: 'number'
│   ├── func_name: 'factorial'
│   └── params: [n]
├── stmt: AssignNode
│   └── expr: OpenFunctionNode
│       ├── func_name: 'factorial'
│       └── arg_0: LiteralNode
│           ├── value: 4
│           └── type: 'number'
└── stmt: DisplayNode
    └── expr: VarAccessNode
        └── var_name: 'res'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0MAKE_FUNCTION('factorial', ['n'], )
1STORE_VAR'factorial'
2LOAD_VAR'factorial'
3__firstlineno__4
4CALL_FUNCTION1
5STORE_VAR('res', None)
6MOVE_VAR'res'
7DISPLAYNone

Review Exercises

  1. Implement a recursive function to compute the Nth Fibonacci number.
  2. Explain how the DJVM handles memory during recursive calls.
Part I

DATA STRUCTURES

Working with lists and collections using the group type.
Chapter 23

Lists (group)

Programs frequently need to manage lists of data, such as a list of names, numbers, or records. In DJPROCODE, these collection structures are represented by the group data type. Syntax: store as group = [, , ...] store = [] (Empty list) Lists can contain elements of any data type, including numbers, points, words, logics, and even other lists. This makes the group type highly flexible. Under the hood, the group mapping uses Python lists, which means they are dynamically sized. You can create lists of arbitrary lengths and pass them to functions. In this chapter, we will explore list declarations, representations, and compilation properties.

DJPROCODE Source Implementation

snippet_ch23.djpc
start
    store myGroup as group = [10, 20, 30]
    display myGroup
stop

Python Equivalency Code

snippet_ch23.py
myGroup = [10, 20, 30]
print(myGroup)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'2
2IDENTIFIER'myGroup'2
3KEYWORD'as'2
4KEYWORD'group'2
5ASSIGNNone2
6LBRACKETNone2
7NUMBER102
8COMMANone2
9NUMBER202
10COMMANone2
11NUMBER302
12RBRACKETNone2
13KEYWORD'display'3
14IDENTIFIER'myGroup'3
15KEYWORD'stop'4
16EOFNone4

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: StoreNode
│   ├── expr: LiteralNode
│   │   ├── value: [, , ]
│   │   └── type: 'group'
│   └── datatype: 'group'
└── stmt: DisplayNode
    └── expr: VarAccessNode
        └── var_name: 'myGroup'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__10
1__firstlineno__20
2__firstlineno__30
3BUILD_LIST3
4STORE_VAR('myGroup', 'group')
5MOVE_VAR'myGroup'
6DISPLAYNone

Review Exercises

  1. Create a group containing four names of your favorite programming languages.
  2. Display an empty group and check how it prints.
Chapter 24

Accessing List Elements

Once a list is created, we need ways to access individual elements. DJPROCODE uses bracket notation for list indexing, starting at 0. Syntax: store item = myGroup[index] Index Rules: - Index 0 accesses the first element. - Index 1 accesses the second element. - Index N-1 accesses the last element, where N is the length of the list. The interpreter and compiler evaluate index expressions dynamically. This means the index can be a number variable, calculation, or function return: store value = myGroup[indexVar plus 1] If you attempt to access an index that is negative or greater than or equal to the size of the list, the VM will raise a runtime out-of-bounds error. Let's see how indexing is parsed and executed.

DJPROCODE Source Implementation

snippet_ch24.djpc
start
    store arr = [4, 8, 12]
    store val = arr[1]
    display val
stop

Python Equivalency Code

snippet_ch24.py
arr = [4, 8, 12]
val = arr[1]
print(val)

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Create a program that declares a list of 5 items and prints the first and last elements.
  2. What error is raised when index exceeds the collection bounds?
Chapter 25

String Operations

Strings (represented as the word type in DJPROCODE) are indexed sequences of characters. Many programs require manipulating text: joining string segments, extracting individual characters, checking string lengths, or splitting text. DJPROCODE supports several string operations: 1. Concatenation: Joining strings using the plus operator. 2. Character Access: Accessing specific characters within a word using bracket indexing, identical to list indexing: store char = myWord[0] // Gets first letter 3. Interoperability: Standard string methods can be invoked on word variables by leveraging Python's native string methods through the property-access dot notation. Let's look at an example that accesses individual characters and performs concatenations.

DJPROCODE Source Implementation

snippet_ch25.djpc
start
    store text = "DJPROCODE"
    store char = text[0]
    display "First letter: " plus char
stop

Python Equivalency Code

snippet_ch25.py
text = "DJPROCODE"
char = text[0]
print("First letter: " + char)

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Write a program that displays the length of a word by calling its python length method.
  2. Print a welcome message that extracts the initials of a name.
Part I

OBJECT-ORIENTED DJPROCODE

Python-bound object bindings and references in the VM.
Chapter 26

Classes and Objects

DJPROCODE is designed to interface cleanly with underlying systems. Rather than reinventing class declaration keywords, DJPROCODE implements a bound object model. Under this model, any complex entity in DJPROCODE is represented as an Object. An object is a collection of property bindings and functions (methods). The DJVM is engineered on top of Python, which allows DJPROCODE variables to store and pass references to native objects. This enables: 1. High performance: Object operations map directly to Python's memory model. 2. Native binding: Easily wrapping operating system resources, GUI frames, or network sockets into objects and manipulating them. 3. Clean namespace structure: Organizing state and behavior together. In the interpreter, property lookups and method executions are resolved dynamically using reflection. We will see how this enables powerful integrations like GUI windows and AI models.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Explain the difference between a variable holding a primitive value and one holding an object reference.
  2. How does the interpreter resolve property lookups?
Chapter 27

Methods

Methods are functions defined inside an object that operate on that object's local state. In DJPROCODE, calling a method uses dot notation followed by parameter arguments. Syntax: store result = obj.methodName(arg1, arg2) In the parser, this constructs a MethodCallNode. The parser advances past the variable name, reads the dot, captures the method identifier, matches parentheses, collects arguments, and packages them into the AST. When executed, the VM resolves the method dynamically. First, the object reference is retrieved from the stack. Then, Python reflection scans the object for a method matching the name, evaluates argument objects, and executes the code. This makes calling methods on lists, strings, and system utilities look identical to modern scripting languages, maintaining readability and programming standard conventions.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Define a list and call its python append method to insert an element.
  2. Explain how arguments are passed from the DJVM stack to native methods.
Chapter 28

Properties and Instantiation

Properties are variable fields stored inside an object. In DJPROCODE, properties are read using the dot syntax: Syntax: store value = obj.propertyName During parsing, this is represented as a PropertyAccessNode. The interpreter evaluates the object expression first, then uses Python's getattr built-in to look up the field value. Object Instantiation: Creating new instances of objects is handled by constructor functions. For example, standard libraries expose initialization functions that return object wrappers. A GUI window object can be initialized, properties modified (e.g., width, title), and methods invoked to display the frame. By keeping property access lightweight and unified, DJPROCODE achieves clean data encapsulation without adding keyword overhead to the compiler specification.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Given a mock object, write code to access its 'id' property.
  2. Explain how instantiation is performed without a 'new' keyword.
Part I

STANDARD LIBRARY

Complete reference for core built-ins: conversions, math, and outputs.
Chapter 29

Built-in Functions

Built-in functions are core routines that are registered in the global environment of every DJPROCODE script. You do not need to import any packages or modules to use them. The core built-ins are: 1. Type Conversion: - makeNumber(x): Converts a string or decimal to an integer. - makePoint(x): Converts a string or integer to a decimal. - makeWord(x): Converts any value to its string representation. 2. Math Utilities: - root(x): Computes the square root of a number. - round(x): Rounds a decimal to the nearest integer. These functions are registered in the VM during initialization: self.global_env["makeNumber"] = lambda args: int(args[0]) This direct binding ensures that built-ins execute at native C/Python speeds, optimizing data processing loops. Let's see them in action.

DJPROCODE Source Implementation

snippet_ch29.djpc
start
    store num = open makeNumber("15")
    store rootVal = open root(100)
    display num plus rootVal
stop

Python Equivalency Code

snippet_ch29.py
num = int("15")
rootVal = 100 ** 0.5
print(num + rootVal)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'2
2IDENTIFIER'num'2
3ASSIGNNone2
4KEYWORD'open'2
5IDENTIFIER'makeNumber'2
6LPARENNone2
7STRING'15'2
8RPARENNone2
9KEYWORD'store'3
10IDENTIFIER'rootVal'3
11ASSIGNNone3
12KEYWORD'open'3
13IDENTIFIER'root'3
14LPARENNone3
15NUMBER1003
16RPARENNone3
17KEYWORD'display'4
18IDENTIFIER'num'4
19KEYWORD'plus'4
20IDENTIFIER'rootVal'4
21KEYWORD'stop'5
22EOFNone5

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: AssignNode
│   └── expr: OpenFunctionNode
│       ├── func_name: 'makeNumber'
│       └── arg_0: LiteralNode
│           ├── value: '15'
│           └── type: 'word'
├── stmt: AssignNode
│   └── expr: OpenFunctionNode
│       ├── func_name: 'root'
│       └── arg_0: LiteralNode
│           ├── value: 100
│           └── type: 'number'
└── stmt: DisplayNode
    └── expr: BinOpNode
        ├── left: VarAccessNode
        │   └── var_name: 'num'
        └── right: VarAccessNode
            └── var_name: 'rootVal'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0LOAD_VAR'makeNumber'
1__firstlineno__'15'
2CALL_FUNCTION1
3STORE_VAR('num', None)
4LOAD_VAR'root'
5__firstlineno__100
6CALL_FUNCTION1
7STORE_VAR('rootVal', None)
8MOVE_VAR'num'
9MOVE_VAR'rootVal'
10BINARY_OP'plus'
11DISPLAYNone

Review Exercises

  1. Convert the string '9.81' to a point, round it, and print the result.
  2. Write a script that takes input and checks if it can be successfully parsed to a number.
Chapter 30

Math Library

For advanced calculations, DJPROCODE provides a standard math library. In addition to the built-in root and round functions, the SDK ships with stdlib/math.djpc, a module written directly in DJPROCODE. Let's look at the mathematical routines included: - absolute(num): Returns the absolute (positive) value of a number. Algorithm: If the number is less than 0, multiply it by -1, otherwise return it. Because this library is written in DJPROCODE, it serves as an excellent demonstration of modular design and function return flows. Developers can examine its source code, understand the logic, and even expand it with custom functions (like power calculations or trigonometry approximations). In this chapter, we walk through the math library implementation and trace how mathematical expressions are evaluated in the VM.

DJPROCODE Source Implementation

snippet_ch30.djpc
start
    create absolute(num)
        check num small 0
            send back num into (0 minus 1)
        stop
        send back num
    stop
    
    store x = open absolute(0 minus 25)
    display x
stop

Python Equivalency Code

snippet_ch30.py
def absolute(num):
    if num < 0:
        return num * -1
    return num

x = absolute(-25)
print(x)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'create'2
2IDENTIFIER'absolute'2
3LPARENNone2
4IDENTIFIER'num'2
5RPARENNone2
6KEYWORD'check'3
7IDENTIFIER'num'3
8KEYWORD'small'3
9NUMBER03
10KEYWORD'send'4
11KEYWORD'back'4
12IDENTIFIER'num'4
13KEYWORD'into'4
14LPARENNone4
15NUMBER04
16KEYWORD'minus'4
17NUMBER14
18RPARENNone4
19KEYWORD'stop'5
20KEYWORD'send'6
21KEYWORD'back'6
22IDENTIFIER'num'6
23KEYWORD'stop'7
24KEYWORD'store'9
25IDENTIFIER'x'9
26ASSIGNNone9
27KEYWORD'open'9
28IDENTIFIER'absolute'9
29LPARENNone9
30NUMBER09
31KEYWORD'minus'9
32NUMBER259
33RPARENNone9
34KEYWORD'display'10
35IDENTIFIER'x'10
36KEYWORD'stop'11
37EOFNone11

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: CreateFunctionNode
│   ├── stmt: CheckNode
│   │   ├── case_0_cond: BinOpNode
│   │   │   ├── left: VarAccessNode
│   │   │   │   └── var_name: 'num'
│   │   │   └── right: LiteralNode
│   │   │       ├── value: 0
│   │   │       └── type: 'number'
│   │   └── case_0_stmt_0: ReturnNode
│   │       └── expr: BinOpNode
│   │           ├── left: VarAccessNode
│   │           │   └── var_name: 'num'
│   │           └── right: BinOpNode
│   │               ├── left: LiteralNode
│   │               │   ├── value: 0
│   │               │   └── type: 'number'
│   │               └── right: LiteralNode
│   │                   ├── value: 1
│   │                   └── type: 'number'
│   ├── stmt: ReturnNode
│   │   └── expr: VarAccessNode
│   │       └── var_name: 'num'
│   ├── func_name: 'absolute'
│   └── params: [num]
├── stmt: AssignNode
│   └── expr: OpenFunctionNode
│       ├── func_name: 'absolute'
│       └── arg_0: BinOpNode
│           ├── left: LiteralNode
│           │   ├── value: 0
│           │   └── type: 'number'
│           └── right: LiteralNode
│               ├── value: 25
│               └── type: 'number'
└── stmt: DisplayNode
    └── expr: VarAccessNode
        └── var_name: 'x'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0MAKE_FUNCTION('absolute', ['num'], )
1STORE_VAR'absolute'
2LOAD_VAR'absolute'
3__firstlineno__0
4__firstlineno__25
5BINARY_OP'minus'
6CALL_FUNCTION1
7STORE_VAR('x', None)
8MOVE_VAR'x'
9DISPLAYNone

Review Exercises

  1. Write a function 'minimum' in DJPROCODE that returns the smaller of two numbers.
  2. Expand absolute to handle decimal numbers correctly.
Chapter 31

System Library

The System Library (sys) provides interfaces to communicate with the host operating system. This is crucial for automation scripts, file managers, and terminal utilities. Key capabilities of the system interface: 1. Version Info: Read current DJPROCODE engine release configurations. 2. Argument Parsing: Access command-line parameters passed when starting the script. 3. Path Manipulation: Inspect working directories and file configurations. By utilizing reflection, the DJVM maps system routines to host OS services safely. This guarantees that code remains cross-platform: path joins use correct slash formats on Windows vs Unix, and environment variables are looked up using unified naming schemes.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Explain why cross-platform path handling is important.
  2. How does DJPROCODE parse arguments passed from the terminal?
Chapter 32

Web Library

Networking is a fundamental component of modern applications. The Web Library provides simple commands to fetch remote web resources (HTTP clients) and host web pages (HTTP servers) directly from DJPROCODE scripts. Web features: - Fetching URLs: Read text, JSON, or media payloads from remote web links. - Web Hosting: Start a lightweight HTTP listener on a local port, routing requests to DJPROCODE handler functions. This built-in capability makes DJPROCODE an excellent choice for lightweight REST API services, dev web hosting, and web scraping utilities, requiring no third-party libraries or installation overhead.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Describe the basic structure of an HTTP request handler in DJPROCODE.
  2. What advantages does hosting a dev server inside the compiler bundle offer?
Chapter 33

AI Library

In the era of smart software, AI capabilities must be standard compiler components, not afterthoughts. DJPROCODE is unique in its class by offering native AI bindings directly in the core language. The AI Library provides: 1. Natural Language Interface: Start chat sessions, pass prompts, and retrieve responses from models. 2. Local/Remote Orchestration: Configure API parameters or bind to local inference engines. 3. Structured Outputs: Parse model responses directly into variables. By integrating AI bindings, developers can build smart chatbots, automated classifiers, code generators, and conversational agents with a few lines of code, illustrating DJPROCODE's vision as an AI-oriented programming language.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Write a prompt flow that extracts positive or negative sentiment from a customer comment.
  2. Discuss the safety rules of native AI bindings.
Part I

THE DJPROCODE ECOSYSTEM

Deep dive into virtual machine stack architecture, opcode execution, and frame states.
Chapter 34

DJVM — The Virtual Machine

The DJVM (DJ Virtual Machine) is the execution engine of the DJPROCODE language. Instead of compiling source files directly to CPU machine code (which is platform-specific and high-overhead), the compiler translates code into compact **DJVM Bytecode**. Virtual Machine Architecture: 1. **Instruction Set**: The VM has a fixed set of opcodes, each represented by a number (like 1 for LOAD_CONST, 6 for DISPLAY). 2. **Stack-Based Execution**: DJVM does not use registers to calculate values. Instead, it uses an execution stack. To add two numbers, it pushes the numbers onto the stack, pops them, performs addition, and pushes the result back. 3. **Execution Frames**: When a function is called, the VM pushes a new `Frame` onto its call stack. This frame tracks the local variables (environment), the instruction pointer (IP), and the return address. This design guarantees sandbox execution safety, portability, and fast execution startups, allowing DJPROCODE scripts to execute instantly on any architecture hosting the DJVM.

DJVM Memory Stack State Diagram
Figure 34.1: The DJVM Execution Stack and Variable Binding Frame Pipeline

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Draw a diagram showing how the stack changes during the execution of '3 plus 5 into 2'.
  2. What is the role of the Instruction Pointer (IP) in the execution loop?
Chapter 35

The Compiler Pipeline & Universal Compilation

The compilation of a DJPROCODE program is structured as a pipeline of translation steps, supporting both Virtual Machine execution and native AOT (Ahead-of-Time) compilation: 1. **Lexing (Tokenization)**: The Lexer (`core/lexer.py`) reads the raw text file and groups characters into tokens. It filters out comments and whitespace. 2. **Parsing**: The Parser (`core/parser.py`) reads the tokens and constructs an Abstract Syntax Tree (AST) matching the language grammar rules. 3. **Compiling / VM Execution**: The Compiler (`core/compiler.py`) walks the AST nodes and emits a list of bytecode instructions executed by the Virtual Machine (`core/djvm.py`). 4. **C++ Transpilation (AOT Compilation)**: For maximum performance, the C++ Transpiler (`core/transpiler.py`) converts the AST directly into highly optimized C++ code, matching Rust-like memory safety with native C++ execution speed. 5. **Universal Compilation**: The Platform Builder (`core/builder.py`) orchestrates targeting systems. From one codebase, it generates CMake configuration and target-specific build scripts (`build_windows.bat`, `build_linux.sh`, `build_macos.sh`, `build_android.sh`, `build_ios.sh`, `build_wasm.sh`) to cross-compile the transpiled C++ code.

DJPROCODE Compiler Pipeline Structure
Figure 35.1: Source Code Compilation Steps (Lexing → Parsing → Bytecode Generation)

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Explain how the C++ transpilation phase retains the memory safety checks of the DJPROCODE source.
  2. What is the role of the Platform Builder in target cross-compilation?
Chapter 36

IDE & Editor Extensions

A language is only as good as its tooling. To provide a professional developer experience, DJPROCODE ships with custom integrations for popular modern editors and IDEs: VS Code Extensions: - Split into four distinct, modular VSIX packages located under `vscode-djprocode-*` directories: * **Syntax Highlighting**: Package `djprocode-syntax-1.0.0.vsix` registers the `.djpc` extension and embeds the TextMate grammar. * **Auto-completion**: Package `djprocode-autocomplete-1.0.0.vsix` handles keywords and built-in completions. * **Formatter**: Package `djprocode-formatter-1.0.0.vsix` provides block-level automated formatting and indentation. * **Debugger**: Package `djprocode-debugger-1.0.0.vsix` configures an inline Debug Adapter Protocol (DAP) hook. JetBrains Plug-in: - Located under `jetbrains-djprocode/` and compiled as `djprocode-jetbrains-1.1.0.jar`. - Natively supports both **IntelliJ IDEA** and **PyCharm** platforms by depending on the shared platform SDK. - Automatically synchronizes TextMate grammar rules for keywords and operators. Other Major Editors (`extensions/`): - **Vim / Neovim**: Provides syntax configurations (`djprocode.vim`) and Neovim-specific Lua filetype registration (`init.lua`). - **Emacs**: A dedicated major mode package `djprocode-mode.el` derived from `prog-mode` containing syntax tables and word highlighting. - **Sublime Text**: A YAML-based `djprocode.sublime-syntax` file with detailed scopes. - **Notepad++**: An importable XML-based User Defined Language (UDL 2.1) configuration. By installing these tools, developers gain productivity enhancements like instant syntax error highlighting and shortcut code templates, ensuring that coding in DJPROCODE is as comfortable as in major mainstream languages.

DJPROCODE Language Tools Ecosystem
Figure 36.1: Language Ecosystem integration showing VSCode / JetBrains IDE wrappers

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Describe the difference between the modular VS Code extensions and how they are installed.
  2. How do you import the DJPROCODE User Defined Language configuration into Notepad++?
Chapter 37

Package System (import)

As codebases grow, they must be partitioned into multiple files. DJPROCODE supports script partitioning and dependency management using the import keyword. Syntax: import When the compiler detects an import keyword: 1. It searches the standard library directory (`stdlib/`) and the local project folder for a file matching `.djpc`. 2. It compiles the imported script into its own code object. 3. It loads the compiled module's environment bindings into the parent file's execution environment. This allows sharing math helper scripts, network wrappers, and utility files across different projects, preventing code replication and promoting modular coding principles.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Create a module 'utils.djpc' with a hello function, and import it into 'main.djpc'.
  2. Discuss how namespace conflicts are managed in the import pipeline.
Part I

ADVANCED TOPICS

Reading and writing files on the local disk.
Chapter 38

File Handling

Persistent storage is required for applications that need to save configuration data, log diagnostics, or store user information. DJPROCODE supports file operations using built-in file methods that operate on text files. Key File Operations: 1. **Open**: Instantiate a file reference on disk. 2. **Read**: Retrieve the contents of a file as a string. 3. **Write**: Output text data to a file. 4. **Close**: Release the file handle to free system memory resources. In this chapter, we explore how variables bind to disk files and walk through coding patterns for writing log text files, reading structured configurations, and managing file handle closures safely.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Write a script that creates a log file and appends the text 'System Ready' to it.
  2. Explain what happens if you attempt to write to a write-protected directory.
Chapter 39

AI Programming in DJPROCODE

Programming in the era of intelligence requires tools designed for reasoning, not just computation. DJPROCODE is designed to facilitate creating conversational loops, structured prompt systems, and agent pipelines natively. Key Patterns: - Prompt Binding: Constructing prompts using variables and passing them directly to AI objects. - Conversational Loops: Wrapping chat loops inside `until` statements to allow continuous human-agent interactions. - Agent Orchestration: Instantiating multiple models and routing outputs from one agent to another as inputs. By keeping these patterns clean and standard, DJPROCODE allows building intelligent automation agents with a fraction of the code required in legacy languages.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Construct a simple translation script that converts user inputs into Spanish using AI queries.
  2. Discuss how you would design an automated email classifier.
Chapter 40

GUI Programming

Desktop applications need graphical user interfaces (GUIs) to be user-friendly. DJPROCODE includes a native GUI window library that maps directly to OS window systems. GUI Components: 1. **WINDOW**: The main window frame container (e.g. `WINDOW "App Name" { ... }`). 2. **BUTTON**: Interactive button controls. 3. **TEXTBOX**: Input text boxes. 4. **LABEL**: Informational text labels. In the interpreter model, the GUI engine translates these declarations into system frames (using Tkinter/PyQt under the hood). This allows developers to build user entry panels, control dashboards, and interactive calculators with simple, structured declarations.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Design the layout for a simple login screen with fields for username and password.
  2. Explain how button click event handlers are registered in DJPROCODE.
Chapter 41

Error Handling Best Practices

Software bugs are inevitable. A robust programming language must provide clear error diagnostics and tools to handle errors at runtime. In DJPROCODE, errors are divided into three stages: 1. **Syntax Errors**: Raised by the Lexer/Parser when code violates spelling or grammatical structures. These prevent compilation and point directly to the line number and illegal symbol. 2. **Type/Compile Warnings**: Raised by the Compiler when variables are used in ways that do not match their declared types. 3. **Runtime Exceptions**: Raised during execution by the DJVM (e.g., Stack Underflow, Division by Zero, Variable Not Found). To build resilient programs: - Validate user input before parsing or performing math calculations. - Use explicit type casting to clarify data transitions. - Read error messages carefully; they contain stack traces and context information. In this chapter, we outline strategies for diagnosing compile errors and writing safe code loops.

DJPROCODE Source Implementation

snippet_ch41.djpc
start
    // Safe division check
    store a = 10
    store b = 0
    
    check b same 0
        display "Error: Cannot divide by zero!"
    otherwise
        display a by b
    stop
stop

Python Equivalency Code

snippet_ch41.py
a = 10
b = 0
if b == 0:
    print("Error: Cannot divide by zero!")
else:
    print(a / b)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'3
2IDENTIFIER'a'3
3ASSIGNNone3
4NUMBER103
5KEYWORD'store'4
6IDENTIFIER'b'4
7ASSIGNNone4
8NUMBER04
9KEYWORD'check'6
10IDENTIFIER'b'6
11KEYWORD'same'6
12NUMBER06
13KEYWORD'display'7
14STRING'Error: Cannot divide by zero!'7
15KEYWORD'otherwise'8
16KEYWORD'display'9
17IDENTIFIER'a'9
18KEYWORD'by'9
19IDENTIFIER'b'9
20KEYWORD'stop'10
21KEYWORD'stop'11
22EOFNone11

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 10
│       └── type: 'number'
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 0
│       └── type: 'number'
└── stmt: CheckNode
    ├── case_0_cond: BinOpNode
    │   ├── left: VarAccessNode
    │   │   └── var_name: 'b'
    │   └── right: LiteralNode
    │       ├── value: 0
    │       └── type: 'number'
    ├── case_0_stmt_0: DisplayNode
    │   └── expr: LiteralNode
    │       ├── value: 'Error: Cannot divide by zero!'
    │       └── type: 'word'
    └── otherwise_stmt_0: DisplayNode
        └── expr: BinOpNode
            ├── left: VarAccessNode
            │   └── var_name: 'a'
            └── right: VarAccessNode
                └── var_name: 'b'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__10
1STORE_VAR('a', None)
2__firstlineno__0
3STORE_VAR('b', None)
4MOVE_VAR'b'
5__firstlineno__0
6BINARY_OP'same'
7JUMP_IF_FALSE11
8__firstlineno__'Error: Cannot divide by zero!'
9DISPLAYNone
10JUMP15
11MOVE_VAR'a'
12MOVE_VAR'b'
13BINARY_OP'by'
14DISPLAYNone

Review Exercises

  1. Write a script that checks if a list is empty before attempting to index it.
  2. Create a custom error message flow for an out-of-bounds user index entry.
Chapter 42

Performance Optimization

High performance is essential for long-running computations. To optimize DJPROCODE applications, developers should understand how the compiler translates code to DJVM bytecode and how the VM executes those instructions. Optimization Techniques: 1. **Reduce Variable Lookups**: Accessing local variables inside frames is faster than looking up global scope variables. 2. **Minimize Type Conversions**: Converting strings to numbers inside tight loops adds computational overhead. Perform conversions once, outside of loops. 3. **Avoid Unnecessary Jumps**: Structure conditions to evaluate standard paths first, reducing branching steps. 4. **Leverage Stack Operators**: Use local expressions directly instead of saving intermediate values to temporary variables. By profiling the generated bytecode index footprint, developers can optimize hot paths, ensuring that DJPROCODE programs run with maximum efficiency inside the VM.

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Compare the bytecode length of an expression written with temporary variables vs. written inline.
  2. Discuss the performance benefits of local scoping.
Part I

COMPLETE PROGRAMS & PROJECTS

Creating several variants of Hello World to learn the foundations.
Chapter 43

Project 1 — Hello World variations

The 'Hello World' program is the traditional first step when learning a new language. To master DJPROCODE's syntax, we will build three variants of this classic program: 1. **The Standard CLI variant**: Prints a simple greeting message to the console. 2. **The Dynamic iteration variant**: Prompts the user to enter their name and iterates a greeting loop based on user input. 3. **The Scoped Function variant**: Encapsulates the printing logic inside a reusable function with parameter passing. By exploring these variations, developers learn how block structures, user inputs, ranges, and functions tie together in a complete program. Let's see the code and trace how the dynamic iteration variant executes.

AST Example Diagram
Figure 43.1: Complete AST Node layout for a compound print statement

DJPROCODE Source Implementation

snippet_ch43.djpc
start
    take "Name: " in user
    count i from 1 to 2
        display "Hello " plus user
    stop
stop

Python Equivalency Code

snippet_ch43.py
user = input("Name: ")
for i in range(1, 3):
    print("Hello " + user)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'take'2
2STRING'Name: '2
3KEYWORD'in'2
4IDENTIFIER'user'2
5KEYWORD'count'3
6IDENTIFIER'i'3
7KEYWORD'from'3
8NUMBER13
9KEYWORD'to'3
10NUMBER23
11KEYWORD'display'4
12STRING'Hello '4
13KEYWORD'plus'4
14IDENTIFIER'user'4
15KEYWORD'stop'5
16KEYWORD'stop'6
17EOFNone6

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: TakeNode
│   └── var_name: 'user'
└── stmt: CountLoopNode
    ├── stmt: DisplayNode
    │   └── expr: BinOpNode
    │       ├── left: LiteralNode
    │       │   ├── value: 'Hello '
    │       │   └── type: 'word'
    │       └── right: VarAccessNode
    │           └── var_name: 'user'
    └── var_name: 'i'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__'Name: '
1TAKE_PROMPT'user'
2__firstlineno__1
3STORE_VAR'i'
4LOAD_VAR'i'
5__firstlineno__2
6BINARY_OP'smallsame'
7JUMP_IF_FALSE17
8__firstlineno__'Hello '
9MOVE_VAR'user'
10BINARY_OP'plus'
11DISPLAYNone
12LOAD_VAR'i'
13__firstlineno__1
14BINARY_OP'plus'
15STORE_VAR'i'
16JUMP4

Review Exercises

  1. Modify the program to repeat the welcome message 5 times.
  2. Encapsulate the loop inside a function greetLoop(name, count) and open it.
Chapter 44

Project 2 — Calculator

A calculator is a great project for testing control flow and arithmetic processing. We will build a CLI calculator that supports five mathematical operations: Addition, Subtraction, Multiplication, Division, and Modulo. Program Flow: 1. Display a menu showing the operation options. 2. Prompt the user to enter their choice (1 to 5). 3. Prompt the user to enter two numbers. 4. Convert choices and numbers to correct data types. 5. Use a `choose` statement to run the correct math operation. 6. Display the final result. By utilizing `choose`/`case`, the program branches cleanly into the selected mathematical operation, validating inputs and displaying outputs in an interactive loop.

DJPROCODE Source Implementation

snippet_ch44.djpc
start
    display "1. Add 2. Sub 3. Mul 4. Div"
    take "Choice: " in chStr
    store ch = open makeNumber(chStr)
    
    take "Num 1: " in aStr
    take "Num 2: " in bStr
    store a = open makeNumber(aStr)
    store b = open makeNumber(bStr)
    
    choose ch
        case 1
            display a plus b
        stop
        case 2
            display a minus b
        stop
        case 3
            display a into b
        stop
        case 4
            display a by b
        stop
    stop
stop

Python Equivalency Code

snippet_ch44.py
print("1. Add 2. Sub 3. Mul 4. Div")
ch = int(input("Choice: "))
a = int(input("Num 1: "))
b = int(input("Num 2: "))
match ch:
    case 1: print(a + b)
    case 2: print(a - b)
    case 3: print(a * b)
    case 4: print(a / b)

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'display'2
2STRING'1. Add 2. Sub 3. Mul 4. Div'2
3KEYWORD'take'3
4STRING'Choice: '3
5KEYWORD'in'3
6IDENTIFIER'chStr'3
7KEYWORD'store'4
8IDENTIFIER'ch'4
9ASSIGNNone4
10KEYWORD'open'4
11IDENTIFIER'makeNumber'4
12LPARENNone4
13IDENTIFIER'chStr'4
14RPARENNone4
15KEYWORD'take'6
16STRING'Num 1: '6
17KEYWORD'in'6
18IDENTIFIER'aStr'6
19KEYWORD'take'7
20STRING'Num 2: '7
21KEYWORD'in'7
22IDENTIFIER'bStr'7
23KEYWORD'store'8
24IDENTIFIER'a'8
25ASSIGNNone8
26KEYWORD'open'8
27IDENTIFIER'makeNumber'8
28LPARENNone8
29IDENTIFIER'aStr'8
30RPARENNone8
31KEYWORD'store'9
32IDENTIFIER'b'9
33ASSIGNNone9
34KEYWORD'open'9
35IDENTIFIER'makeNumber'9
36LPARENNone9
37IDENTIFIER'bStr'9
38RPARENNone9
39KEYWORD'choose'11
40IDENTIFIER'ch'11
41KEYWORD'case'12
42NUMBER112
43KEYWORD'display'13
44IDENTIFIER'a'13
45KEYWORD'plus'13
46IDENTIFIER'b'13
47KEYWORD'stop'14
48KEYWORD'case'15
49NUMBER215
50KEYWORD'display'16
51IDENTIFIER'a'16
52KEYWORD'minus'16
53IDENTIFIER'b'16
54KEYWORD'stop'17
55KEYWORD'case'18
56NUMBER318
57KEYWORD'display'19
58IDENTIFIER'a'19
59KEYWORD'into'19
60IDENTIFIER'b'19
61KEYWORD'stop'20
62KEYWORD'case'21
63NUMBER421
64KEYWORD'display'22
65IDENTIFIER'a'22
66KEYWORD'by'22
67IDENTIFIER'b'22
68KEYWORD'stop'23
69KEYWORD'stop'24
70KEYWORD'stop'25
71EOFNone25

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: DisplayNode
│   └── expr: LiteralNode
│       ├── value: '1. Add 2. Sub 3. Mul 4. Div'
│       └── type: 'word'
├── stmt: TakeNode
│   └── var_name: 'chStr'
├── stmt: AssignNode
│   └── expr: OpenFunctionNode
│       ├── func_name: 'makeNumber'
│       └── arg_0: VarAccessNode
│           └── var_name: 'chStr'
├── stmt: TakeNode
│   └── var_name: 'aStr'
├── stmt: TakeNode
│   └── var_name: 'bStr'
├── stmt: AssignNode
│   └── expr: OpenFunctionNode
│       ├── func_name: 'makeNumber'
│       └── arg_0: VarAccessNode
│           └── var_name: 'aStr'
├── stmt: AssignNode
│   └── expr: OpenFunctionNode
│       ├── func_name: 'makeNumber'
│       └── arg_0: VarAccessNode
│           └── var_name: 'bStr'
└── stmt: ChooseNode
    ├── case_0: (, [], False)
    ├── case_1: (, [], False)
    ├── case_2: (, [], False)
    ├── case_3: (, [], False)
    └── var_name: 'ch'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__'1. Add 2. Sub 3. Mul 4. Div'
1DISPLAYNone
2__firstlineno__'Choice: '
3TAKE_PROMPT'chStr'
4LOAD_VAR'makeNumber'
5MOVE_VAR'chStr'
6CALL_FUNCTION1
7STORE_VAR('ch', None)
8__firstlineno__'Num 1: '
9TAKE_PROMPT'aStr'
10__firstlineno__'Num 2: '
11TAKE_PROMPT'bStr'
12LOAD_VAR'makeNumber'
13MOVE_VAR'aStr'
14CALL_FUNCTION1
15STORE_VAR('a', None)
16LOAD_VAR'makeNumber'
17MOVE_VAR'bStr'
18CALL_FUNCTION1
19STORE_VAR('b', None)
20LOAD_VAR'ch'
21DUPNone
22__firstlineno__1
23BINARY_OP'same'
24JUMP_IF_FALSE31
25POPNone
26MOVE_VAR'a'
27MOVE_VAR'b'
28BINARY_OP'plus'
29DISPLAYNone
30JUMP62
31DUPNone
32__firstlineno__2
33BINARY_OP'same'
34JUMP_IF_FALSE41
35POPNone
36MOVE_VAR'a'
37MOVE_VAR'b'
38BINARY_OP'minus'
39DISPLAYNone
40JUMP62
41DUPNone
42__firstlineno__3
43BINARY_OP'same'
44JUMP_IF_FALSE51
45POPNone
46MOVE_VAR'a'
47MOVE_VAR'b'
48BINARY_OP'into'
49DISPLAYNone
50JUMP62
51DUPNone
52__firstlineno__4
53BINARY_OP'same'
54JUMP_IF_FALSE61
55POPNone
56MOVE_VAR'a'
57MOVE_VAR'b'
58BINARY_OP'by'
59DISPLAYNone
60JUMP62
61POPNone

Review Exercises

  1. Add a fifth choice to the calculator for Modulo arithmetic using the remain operator.
  2. Wrap the calculator in an until loop that continues until choice is 0.
Chapter 45

Project 3 — Hotel Management System

The Hotel Management System is the flagship demonstration program for the DJPROCODE language. It implements a complete customer billing flow, showcasing variables, nested choose-case statements, user input casting, and complex arithmetic operations (like 18% tax and delivery charges). The program structure consists of: 1. Collecting customer details (name, table number, number of guests). 2. Presenting a nested menu for Starters, Main Course, Drinks, and Desserts. 3. Calculating food subtotals. 4. Prompting for delivery preferences and adding a flat delivery charge. 5. Calculating 18% GST (tax) and adding it to the subtotal. 6. Displaying a professionally formatted invoice showing customer details, items, subtotal, tax, delivery, and grand total. This project is a perfect test of how a program compiles, resolves execution frames, and evaluates complex arithmetic combinations in the DJVM.

DJPROCODE Source Implementation

snippet_ch45.djpc
start
    store total = 0
    take "Name: " in custName
    display "1 => Starters 2 => Main"
    take "Choice: " in catStr
    store cat = open makeNumber(catStr)
    
    choose cat
        case 1
            display "1. Fries Rs.100"
            take "Item: " in stStr
            store st = open makeNumber(stStr)
            check st same 1
                store total = total plus 100
            stop
        stop
    stop
    
    store tax = (total into 18) by 100
    store grand = total plus tax
    display "Total Bill: Rs." plus grand
stop

Python Equivalency Code

snippet_ch45.py
total = 0
custName = input("Name: ")
print("1 => Starters 2 => Main")
cat = int(input("Choice: "))
if cat == 1:
    print("1. Fries Rs.100")
    st = int(input("Item: "))
    if st == 1:
        total = total + 100

tax = (total * 18) / 100
grand = total + tax
print("Total Bill: Rs." + str(grand))

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'2
2IDENTIFIER'total'2
3ASSIGNNone2
4NUMBER02
5KEYWORD'take'3
6STRING'Name: '3
7KEYWORD'in'3
8IDENTIFIER'custName'3
9KEYWORD'display'4
10STRING'1 => Starters 2 => Main'4
11KEYWORD'take'5
12STRING'Choice: '5
13KEYWORD'in'5
14IDENTIFIER'catStr'5
15KEYWORD'store'6
16IDENTIFIER'cat'6
17ASSIGNNone6
18KEYWORD'open'6
19IDENTIFIER'makeNumber'6
20LPARENNone6
21IDENTIFIER'catStr'6
22RPARENNone6
23KEYWORD'choose'8
24IDENTIFIER'cat'8
25KEYWORD'case'9
26NUMBER19
27KEYWORD'display'10
28STRING'1. Fries Rs.100'10
29KEYWORD'take'11
30STRING'Item: '11
31KEYWORD'in'11
32IDENTIFIER'stStr'11
33KEYWORD'store'12
34IDENTIFIER'st'12
35ASSIGNNone12
36KEYWORD'open'12
37IDENTIFIER'makeNumber'12
38LPARENNone12
39IDENTIFIER'stStr'12
40RPARENNone12
41KEYWORD'check'13
42IDENTIFIER'st'13
43KEYWORD'same'13
44NUMBER113
45KEYWORD'store'14
46IDENTIFIER'total'14
47ASSIGNNone14
48IDENTIFIER'total'14
49KEYWORD'plus'14
50NUMBER10014
51KEYWORD'stop'15
52KEYWORD'stop'16
53KEYWORD'stop'17
54KEYWORD'store'19
55IDENTIFIER'tax'19
56ASSIGNNone19
57LPARENNone19
58IDENTIFIER'total'19
59KEYWORD'into'19
60NUMBER1819
61RPARENNone19
62KEYWORD'by'19
63NUMBER10019
64KEYWORD'store'20
65IDENTIFIER'grand'20
66ASSIGNNone20
67IDENTIFIER'total'20
68KEYWORD'plus'20
69IDENTIFIER'tax'20
70KEYWORD'display'21
71STRING'Total Bill: Rs.'21
72KEYWORD'plus'21
73IDENTIFIER'grand'21
74KEYWORD'stop'22
75EOFNone22

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 0
│       └── type: 'number'
├── stmt: TakeNode
│   └── var_name: 'custName'
├── stmt: DisplayNode
│   └── expr: LiteralNode
│       ├── value: '1 => Starters 2 => Main'
│       └── type: 'word'
├── stmt: TakeNode
│   └── var_name: 'catStr'
├── stmt: AssignNode
│   └── expr: OpenFunctionNode
│       ├── func_name: 'makeNumber'
│       └── arg_0: VarAccessNode
│           └── var_name: 'catStr'
└── stmt: ChooseNode
    ├── case_0: (, [, , , , , , ], False)
    └── var_name: 'cat'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__0
1STORE_VAR('total', None)
2__firstlineno__'Name: '
3TAKE_PROMPT'custName'
4__firstlineno__'1 => Starters 2 => Main'
5DISPLAYNone
6__firstlineno__'Choice: '
7TAKE_PROMPT'catStr'
8LOAD_VAR'makeNumber'
9MOVE_VAR'catStr'
10CALL_FUNCTION1
11STORE_VAR('cat', None)
12LOAD_VAR'cat'
13DUPNone
14__firstlineno__1
15BINARY_OP'same'
16JUMP_IF_FALSE50
17POPNone
18__firstlineno__'1. Fries Rs.100'
19DISPLAYNone
20__firstlineno__'Item: '
21TAKE_PROMPT'stStr'
22LOAD_VAR'makeNumber'
23MOVE_VAR'stStr'
24CALL_FUNCTION1
25STORE_VAR('st', None)
26MOVE_VAR'st'
27__firstlineno__1
28BINARY_OP'same'
29JUMP_IF_FALSE35
30MOVE_VAR'total'
31__firstlineno__100
32BINARY_OP'plus'
33STORE_VAR('total', None)
34JUMP35
35MOVE_VAR'total'
36__firstlineno__18
37BINARY_OP'into'
38__firstlineno__100
39BINARY_OP'by'
40STORE_VAR('tax', None)
41MOVE_VAR'total'
42MOVE_VAR'tax'
43BINARY_OP'plus'
44STORE_VAR('grand', None)
45__firstlineno__'Total Bill: Rs.'
46MOVE_VAR'grand'
47BINARY_OP'plus'
48DISPLAYNone
49JUMP51
50POPNone

Review Exercises

  1. Add a 'Desserts' category to the hotel billing logic.
  2. Write a function printBill(name, total, tax) to print the formatted invoice.
Chapter 46

Project 4 — Student Grade System

Managing student grades requires data aggregation and score classification. In this project, we build a student marks system that collects grades for three subjects (Math, Science, English), computes the average score, and outputs a letter grade (A, B, C, D, or F) based on standard limits. Key operations: 1. Input student name and marks for 3 subjects. 2. Sum the scores and divide by 3 to find the average point. 3. Chain multiple check-otherwise statements to classify the score: - Average >= 90: Grade A - Average >= 80: Grade B - Average >= 70: Grade C - Average >= 60: Grade D - Average < 60: Grade F 4. Display a report card summarizing the student's status. This script demonstrates data casting, arithmetic aggregation, and conditional chaining in a practical application.

DJPROCODE Source Implementation

snippet_ch46.djpc
start
    take "Math: " in mStr
    take "Science: " in sStr
    store m = open makeNumber(mStr)
    store s = open makeNumber(sStr)
    store avg = (m plus s) by 2
    
    display "Average: " plus avg
    check avg bigsame 90
        display "Grade: A"
    otherwise check avg bigsame 80
        display "Grade: B"
    otherwise
        display "Grade: C"
    stop
stop

Python Equivalency Code

snippet_ch46.py
m = int(input("Math: "))
s = int(input("Science: "))
avg = (m + s) / 2
print("Average: " + str(avg))
if avg >= 90:
    print("Grade: A")
elif avg >= 80:
    print("Grade: B")
else:
    print("Grade: C")

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'take'2
2STRING'Math: '2
3KEYWORD'in'2
4IDENTIFIER'mStr'2
5KEYWORD'take'3
6STRING'Science: '3
7KEYWORD'in'3
8IDENTIFIER'sStr'3
9KEYWORD'store'4
10IDENTIFIER'm'4
11ASSIGNNone4
12KEYWORD'open'4
13IDENTIFIER'makeNumber'4
14LPARENNone4
15IDENTIFIER'mStr'4
16RPARENNone4
17KEYWORD'store'5
18IDENTIFIER's'5
19ASSIGNNone5
20KEYWORD'open'5
21IDENTIFIER'makeNumber'5
22LPARENNone5
23IDENTIFIER'sStr'5
24RPARENNone5
25KEYWORD'store'6
26IDENTIFIER'avg'6
27ASSIGNNone6
28LPARENNone6
29IDENTIFIER'm'6
30KEYWORD'plus'6
31IDENTIFIER's'6
32RPARENNone6
33KEYWORD'by'6
34NUMBER26
35KEYWORD'display'8
36STRING'Average: '8
37KEYWORD'plus'8
38IDENTIFIER'avg'8
39KEYWORD'check'9
40IDENTIFIER'avg'9
41KEYWORD'bigsame'9
42NUMBER909
43KEYWORD'display'10
44STRING'Grade: A'10
45KEYWORD'otherwise'11
46KEYWORD'check'11
47IDENTIFIER'avg'11
48KEYWORD'bigsame'11
49NUMBER8011
50KEYWORD'display'12
51STRING'Grade: B'12
52KEYWORD'otherwise'13
53KEYWORD'display'14
54STRING'Grade: C'14
55KEYWORD'stop'15
56KEYWORD'stop'16
57EOFNone16

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: TakeNode
│   └── var_name: 'mStr'
├── stmt: TakeNode
│   └── var_name: 'sStr'
├── stmt: AssignNode
│   └── expr: OpenFunctionNode
│       ├── func_name: 'makeNumber'
│       └── arg_0: VarAccessNode
│           └── var_name: 'mStr'
├── stmt: AssignNode
│   └── expr: OpenFunctionNode
│       ├── func_name: 'makeNumber'
│       └── arg_0: VarAccessNode
│           └── var_name: 'sStr'
├── stmt: AssignNode
│   └── expr: BinOpNode
│       ├── left: BinOpNode
│       │   ├── left: VarAccessNode
│       │   │   └── var_name: 'm'
│       │   └── right: VarAccessNode
│       │       └── var_name: 's'
│       └── right: LiteralNode
│           ├── value: 2
│           └── type: 'number'
├── stmt: DisplayNode
│   └── expr: BinOpNode
│       ├── left: LiteralNode
│       │   ├── value: 'Average: '
│       │   └── type: 'word'
│       └── right: VarAccessNode
│           └── var_name: 'avg'
└── stmt: CheckNode
    ├── case_0_cond: BinOpNode
    │   ├── left: VarAccessNode
    │   │   └── var_name: 'avg'
    │   └── right: LiteralNode
    │       ├── value: 90
    │       └── type: 'number'
    ├── case_0_stmt_0: DisplayNode
    │   └── expr: LiteralNode
    │       ├── value: 'Grade: A'
    │       └── type: 'word'
    ├── case_1_cond: BinOpNode
    │   ├── left: VarAccessNode
    │   │   └── var_name: 'avg'
    │   └── right: LiteralNode
    │       ├── value: 80
    │       └── type: 'number'
    ├── case_1_stmt_0: DisplayNode
    │   └── expr: LiteralNode
    │       ├── value: 'Grade: B'
    │       └── type: 'word'
    └── otherwise_stmt_0: DisplayNode
        └── expr: LiteralNode
            ├── value: 'Grade: C'
            └── type: 'word'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__'Math: '
1TAKE_PROMPT'mStr'
2__firstlineno__'Science: '
3TAKE_PROMPT'sStr'
4LOAD_VAR'makeNumber'
5MOVE_VAR'mStr'
6CALL_FUNCTION1
7STORE_VAR('m', None)
8LOAD_VAR'makeNumber'
9MOVE_VAR'sStr'
10CALL_FUNCTION1
11STORE_VAR('s', None)
12MOVE_VAR'm'
13MOVE_VAR's'
14BINARY_OP'plus'
15__firstlineno__2
16BINARY_OP'by'
17STORE_VAR('avg', None)
18__firstlineno__'Average: '
19MOVE_VAR'avg'
20BINARY_OP'plus'
21DISPLAYNone
22MOVE_VAR'avg'
23__firstlineno__90
24BINARY_OP'bigsame'
25JUMP_IF_FALSE29
26__firstlineno__'Grade: A'
27DISPLAYNone
28JUMP38
29MOVE_VAR'avg'
30__firstlineno__80
31BINARY_OP'bigsame'
32JUMP_IF_FALSE36
33__firstlineno__'Grade: B'
34DISPLAYNone
35JUMP38
36__firstlineno__'Grade: C'
37DISPLAYNone

Review Exercises

  1. Extend the grading logic to assign an A+ grade for average scores above 95.
  2. Compute the average of a list (group) of marks using iteration.
Chapter 47

Project 5 — Number Guessing Game

Games are excellent projects for practicing logical control loops. In this project, we build a Number Guessing Game. The game sets a secret target number, and prompts the user to guess it. Flow: 1. Store a target number (e.g., 7). 2. Start an `until` loop that continues until the user's guess matches the target. 3. Prompt the user to enter their guess. 4. Compare the guess: - If guess is less than target, display "Too Low!". - If guess is greater than target, display "Too High!". - If guess is equal to target, display "Correct!" and exit the loop. 5. Track the number of attempts and print it at the end. This project exercises conditional statements, state modification, and loop controls in a fun, interactive way.

DJPROCODE Source Implementation

snippet_ch47.djpc
start
    store secret = 7
    store guessed = no
    
    until guessed same yes
        take "Guess: " in gStr
        store g = open makeNumber(gStr)
        
        check g same secret
            display "Correct!"
            store guessed = yes
        otherwise check g small secret
            display "Too Low!"
        otherwise
            display "Too High!"
        stop
    stop
stop

Python Equivalency Code

snippet_ch47.py
secret = 7
guessed = False
while not guessed:
    g = int(input("Guess: "))
    if g == secret:
        print("Correct!")
        guessed = True
    elif g < secret:
        print("Too Low!")
    else:
        print("Too High!")

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'2
2IDENTIFIER'secret'2
3ASSIGNNone2
4NUMBER72
5KEYWORD'store'3
6IDENTIFIER'guessed'3
7ASSIGNNone3
8KEYWORD'no'3
9KEYWORD'until'5
10IDENTIFIER'guessed'5
11KEYWORD'same'5
12KEYWORD'yes'5
13KEYWORD'take'6
14STRING'Guess: '6
15KEYWORD'in'6
16IDENTIFIER'gStr'6
17KEYWORD'store'7
18IDENTIFIER'g'7
19ASSIGNNone7
20KEYWORD'open'7
21IDENTIFIER'makeNumber'7
22LPARENNone7
23IDENTIFIER'gStr'7
24RPARENNone7
25KEYWORD'check'9
26IDENTIFIER'g'9
27KEYWORD'same'9
28IDENTIFIER'secret'9
29KEYWORD'display'10
30STRING'Correct!'10
31KEYWORD'store'11
32IDENTIFIER'guessed'11
33ASSIGNNone11
34KEYWORD'yes'11
35KEYWORD'otherwise'12
36KEYWORD'check'12
37IDENTIFIER'g'12
38KEYWORD'small'12
39IDENTIFIER'secret'12
40KEYWORD'display'13
41STRING'Too Low!'13
42KEYWORD'otherwise'14
43KEYWORD'display'15
44STRING'Too High!'15
45KEYWORD'stop'16
46KEYWORD'stop'17
47KEYWORD'stop'18
48EOFNone18

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 7
│       └── type: 'number'
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: False
│       └── type: 'logic'
└── stmt: UntilNode
    ├── stmt: TakeNode
    │   └── var_name: 'gStr'
    ├── stmt: AssignNode
    │   └── expr: OpenFunctionNode
    │       ├── func_name: 'makeNumber'
    │       └── arg_0: VarAccessNode
    │           └── var_name: 'gStr'
    └── stmt: CheckNode
        ├── case_0_cond: BinOpNode
        │   ├── left: VarAccessNode
        │   │   └── var_name: 'g'
        │   └── right: VarAccessNode
        │       └── var_name: 'secret'
        ├── case_0_stmt_0: DisplayNode
        │   └── expr: LiteralNode
        │       ├── value: 'Correct!'
        │       └── type: 'word'
        ├── case_0_stmt_1: AssignNode
        │   └── expr: LiteralNode
        │       ├── value: True
        │       └── type: 'logic'
        ├── case_1_cond: BinOpNode
        │   ├── left: VarAccessNode
        │   │   └── var_name: 'g'
        │   └── right: VarAccessNode
        │       └── var_name: 'secret'
        ├── case_1_stmt_0: DisplayNode
        │   └── expr: LiteralNode
        │       ├── value: 'Too Low!'
        │       └── type: 'word'
        └── otherwise_stmt_0: DisplayNode
            └── expr: LiteralNode
                ├── value: 'Too High!'
                └── type: 'word'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__7
1STORE_VAR('secret', None)
2__firstlineno__False
3STORE_VAR('guessed', None)
4MOVE_VAR'guessed'
5__firstlineno__True
6BINARY_OP'same'
7JUMP_IF_FALSE33
8__firstlineno__'Guess: '
9TAKE_PROMPT'gStr'
10LOAD_VAR'makeNumber'
11MOVE_VAR'gStr'
12CALL_FUNCTION1
13STORE_VAR('g', None)
14MOVE_VAR'g'
15MOVE_VAR'secret'
16BINARY_OP'same'
17JUMP_IF_FALSE23
18__firstlineno__'Correct!'
19DISPLAYNone
20__firstlineno__True
21STORE_VAR('guessed', None)
22JUMP32
23MOVE_VAR'g'
24MOVE_VAR'secret'
25BINARY_OP'small'
26JUMP_IF_FALSE30
27__firstlineno__'Too Low!'
28DISPLAYNone
29JUMP32
30__firstlineno__'Too High!'
31DISPLAYNone
32JUMP4

Review Exercises

  1. Add a counter variable to track how many guesses the user took, and print the score.
  2. Implement a maximum limit of 5 guesses using a count loop and the exit keyword.
Chapter 48

Project 6 — Fibonacci Sequence Generator

The Fibonacci sequence is a sequence of numbers where each number is the sum of the two preceding ones, starting from 0 and 1. Generating this sequence is a classic programming challenge that can be solved using loops or recursion. In this project, we implement both methods in DJPROCODE: 1. **Loop-based approach**: Uses a count loop to calculate sequence values iteratively. This is highly efficient and runs in \(O(N)\) time. 2. **Recursive approach**: Invokes a function recursively. While less efficient for large numbers, it is a elegant demonstration of execution frame nesting. We will compare their performance, look at the compiler instructions generated for both scripts, and analyze how variables mutate during iteration states.

DJPROCODE Source Implementation

snippet_ch48.djpc
start
    store limit = 5
    store a = 0
    store b = 1
    display a
    display b
    count i from 3 to limit
        store next = a plus b
        display next
        store a = b
        store b = next
    stop
stop

Python Equivalency Code

snippet_ch48.py
limit = 5
a = 0
b = 1
print(a)
print(b)
for i in range(3, limit + 1):
    next_val = a + b
    print(next_val)
    a = b
    b = next_val

Key Advantages

Common Pitfalls & Errors

Compilation & Syntax Analysis Tracing

To understand exactly how the compiler parses and processes this chapter's code, review the analysis structures below:

1. Lexer Tokens Table

The lexer breaks the code characters into the following token sequence:

IndexToken TypeLexeme ValueLine
0KEYWORD'start'1
1KEYWORD'store'2
2IDENTIFIER'limit'2
3ASSIGNNone2
4NUMBER52
5KEYWORD'store'3
6IDENTIFIER'a'3
7ASSIGNNone3
8NUMBER03
9KEYWORD'store'4
10IDENTIFIER'b'4
11ASSIGNNone4
12NUMBER14
13KEYWORD'display'5
14IDENTIFIER'a'5
15KEYWORD'display'6
16IDENTIFIER'b'6
17KEYWORD'count'7
18IDENTIFIER'i'7
19KEYWORD'from'7
20NUMBER37
21KEYWORD'to'7
22IDENTIFIER'limit'7
23KEYWORD'store'8
24IDENTIFIER'next'8
25ASSIGNNone8
26IDENTIFIER'a'8
27KEYWORD'plus'8
28IDENTIFIER'b'8
29KEYWORD'display'9
30IDENTIFIER'next'9
31KEYWORD'store'10
32IDENTIFIER'a'10
33ASSIGNNone10
34IDENTIFIER'b'10
35KEYWORD'store'11
36IDENTIFIER'b'11
37ASSIGNNone11
38IDENTIFIER'next'11
39KEYWORD'stop'12
40KEYWORD'stop'13
41EOFNone13

2. Abstract Syntax Tree (AST)

The parser organizes tokens into the following logical tree structure:

ProgramNode
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 5
│       └── type: 'number'
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 0
│       └── type: 'number'
├── stmt: AssignNode
│   └── expr: LiteralNode
│       ├── value: 1
│       └── type: 'number'
├── stmt: DisplayNode
│   └── expr: VarAccessNode
│       └── var_name: 'a'
├── stmt: DisplayNode
│   └── expr: VarAccessNode
│       └── var_name: 'b'
└── stmt: CountLoopNode
    ├── stmt: AssignNode
    │   └── expr: BinOpNode
    │       ├── left: VarAccessNode
    │       │   └── var_name: 'a'
    │       └── right: VarAccessNode
    │           └── var_name: 'b'
    ├── stmt: DisplayNode
    │   └── expr: VarAccessNode
    │       └── var_name: 'next'
    ├── stmt: AssignNode
    │   └── expr: VarAccessNode
    │       └── var_name: 'b'
    ├── stmt: AssignNode
    │   └── expr: VarAccessNode
    │       └── var_name: 'next'
    └── var_name: 'i'

3. Compiled Bytecode Opcodes

The compiler generates the following DJVM assembly instructions:

Instruction AddressBytecode OpcodeInstruction Argument
0__firstlineno__5
1STORE_VAR('limit', None)
2__firstlineno__0
3STORE_VAR('a', None)
4__firstlineno__1
5STORE_VAR('b', None)
6MOVE_VAR'a'
7DISPLAYNone
8MOVE_VAR'b'
9DISPLAYNone
10__firstlineno__3
11STORE_VAR'i'
12LOAD_VAR'i'
13MOVE_VAR'limit'
14BINARY_OP'smallsame'
15JUMP_IF_FALSE31
16MOVE_VAR'a'
17MOVE_VAR'b'
18BINARY_OP'plus'
19STORE_VAR('next', None)
20MOVE_VAR'next'
21DISPLAYNone
22MOVE_VAR'b'
23STORE_VAR('a', None)
24MOVE_VAR'next'
25STORE_VAR('b', None)
26LOAD_VAR'i'
27__firstlineno__1
28BINARY_OP'plus'
29STORE_VAR'i'
30JUMP12

Review Exercises

  1. Write a function printFib(n) that outputs the first N Fibonacci numbers.
  2. Trace the stack execution of the recursive Fibonacci function.
Chapter 49

Project 7 — List Sorting Algorithm

Sorting data is an essential task in computer science. In this project, we implement the **Bubble Sort** algorithm in DJPROCODE. Bubble Sort works by repeatedly swapping adjacent elements if they are in the wrong order. Algorithm steps: 1. Access a list (group) of unsorted numbers. 2. Nest a count loop inside another count loop. 3. Compare adjacent items: index `j` and index `j plus 1`. 4. If the left item is greater than the right, swap their positions in the list. 5. Repeat until the list is fully sorted. This project exercises list element indexing, nested loops, conditional checks, and temporary variable swapping, demonstrating advanced algorithm implementation in DJPROCODE.

DJPROCODE Source Implementation

snippet_ch49.djpc
start
    store arr = [5, 2, 8, 1]
    store temp = 0
    // Simple swap demonstration
    check arr[0] big arr[1]
        store temp = arr[0]
        // arr[0] = arr[1] would be used in full interpreter list mutation
        display "Swap needed"
    stop
stop

Python Equivalency Code

snippet_ch49.py
arr = [5, 2, 8, 1]
if arr[0] > arr[1]:
    temp = arr[0]
    arr[0] = arr[1]
    arr[1] = temp
    print("Swapped")

Key Advantages

Common Pitfalls & Errors

Review Exercises

  1. Complete a full Bubble Sort loop in DJPROCODE to sort a list of 4 items.
  2. Explain how the swap operation is parsed into AST nodes.
Part XII

Reference & Appendix

Keyword tables, formal EBNF grammars, comparisons, and bytecode instruction sets.
Appendix A

Complete Keyword Reference

Definitions, categories, and usage rules for all 88 reserved keywords in DJPROCODE v2.0.

The following table lists every reserved keyword in the DJPROCODE v2.0 specification. These keywords are protected tokens and cannot be used as variable names, function names, or identifiers.

KeywordCategoryPurposeExample
`start`StructureBegins program or block`start`
`stop`StructureEnds program or block`stop`
`display`I/OPrints value to console`display "Hello"`
`store`VariablesDeclares or reassigns variable`store x = 5`
`as`VariablesType separator`store x as number`
`fixed`VariablesDeclares constant`fixed PI = 3.14`
`take`I/OReads user input`take in age`
`in`I/OIdentifies input target`take in name`
`check`Control FlowIf statement condition`check x big 5`
`otherwise`Control FlowElse branch keyword`otherwise`
`choose`Control FlowSwitch block initialization`choose choice`
`case`Control FlowSwitch case path option`case 1`
`default`Control FlowSwitch fallback path`default`
`loop`LoopsSimple count repetition`loop 5`
`until`LoopsNegative condition loop`until x same yes`
`count`LoopsScoped index range loop`count i from 1 to 10`
`from`LoopsRange start keyword`count i from 1`
`to`LoopsRange end keyword`to 10`
`exit`LoopsBreak loop execution`exit`
`skip`LoopsContinue to next loop iteration`skip`
`create`FunctionsDefines a new function`create add(a,b)`
`open`FunctionsInvokes defined function`open add(1,2)`
`send`FunctionsPart of 'send back' (return)`send back`
`back`FunctionsPart of 'send back' (return)`send back result`
`word`TypesText string data type`store s as word`
`number`TypesInteger data type`store n as number`
`point`TypesDecimal float data type`store f as point`
`logic`TypesBoolean true/false type`store b as logic`
`group`TypesList array data type`store l as group`
`nothing`TypesNull data type`store n as nothing`
`yes`LiteralsBoolean true literal`store b = yes`
`no`LiteralsBoolean false literal`store b = no`
`plus`OperatorsAddition / Concatenation`x plus 5`
`minus`OperatorsSubtraction operator`x minus 5`
`into`OperatorsMultiplication operator`x into 5`
`by`OperatorsDivision operator`x by 5`
`remain`OperatorsModulo remainder operator`x remain 5`
`same`OperatorsEquality comparison (==)`x same y`
`notsame`OperatorsInequality comparison (!=)`x notsame y`
`big`OperatorsGreater than check (>)`x big y`
`small`OperatorsLess than check (<)`x small y`
`bigsame`OperatorsGreater or equal check (>=)`x bigsame y`
`smallsame`OperatorsLess or equal check (<=)`x smallsame y`
`both`OperatorsLogical AND operator (&&)`a both b`
`either`OperatorsLogical OR operator ()`a either b`
`reverse`OperatorsLogical NOT operator (!)`reverse flag`
`import`ModulesImports script package`import Math`
`attempt`ExceptionsTry block for error handling`attempt`
`rescue`ExceptionsCatch block for error handling`rescue err`
`ensure`ExceptionsFinally block for error handling`ensure`
`protect`ExceptionsInline crash protection`protect block`
`give`FunctionsImplicit lambda return`give x plus 1`
`make`FunctionsLambda instantiation`make (x) after ...`
`after`FunctionsLambda mapping / callback`make (x) after display x`
`spawn`ConcurrencyStarts concurrent thread`spawn worker()`
`maybe`OptionalsDeclares optional variable`store x as maybe number`
`ifhas`OptionalsUnwraps optional variable`ifhas x as val`
`ornothing`OptionalsOptional fallback value`x ornothing 0`
`else`OptionalsOptional fallback branch`ifhas x as val ... else`
`when`Pattern MatchPattern matching block`when expression`
`record`TypesImmutable structured record`record User(name, id)`
`then`Pattern MatchCase branch action`case 1 then display`
`format`StringsString interpolation helper`format "Value is {x}"`
`freeze`Memory SafetyFreezes object state`freeze obj`
`own`Memory SafetyAsserts memory ownership`store own x = obj`
`safeopen`Memory SafetySafely dereferences scope`safeopen resource`
`blueprint`ClassesDeclares object class`blueprint Car`
`build`ClassesInstantiates class object`build Car()`
`extends`ClassesOOP subclassing inheritance`blueprint Sedan extends Car`
`this`ClassesSelf instance reference`store this.speed = 0`
`super`ClassesParent class reference`open super.init()`
`space`StructureNamespace container declaration`space Utilities`
`static`ClassesDeclares static member`static store count = 0`
`route`Web servingRegisters HTTP url route`route "/home" serving ...`
`serve`Web servingInitiates web server`serve 8080`
`get`Web servingRegisters HTTP GET handler`get "/api" serving ...`
`post`Web servingRegisters HTTP POST handler`post "/api" serving ...`
`put`Web servingRegisters HTTP PUT handler`put "/api" serving ...`
`delete`Web servingRegisters HTTP DELETE handler`delete "/api" serving ...`
`session`Web servingSession context store`store session.user = name`
`template`Web servingRenders HTML template page`template "index.html"`
`formula`Lazy EvalDeclares lazy variable formula`store formula area = w * h`
`checkpoint`TransactionsSavepoint for state rollback`checkpoint "tx1"`
`rollback`TransactionsRollback state to checkpoint`rollback "tx1"`
`approx`OperatorsApproximate float equality`x approx 3.14`
`sort`OperationsSorts list/group elements`sort list ascending`
`ascending`OperationsSorting direction modifier`sort list ascending`
`descending`OperationsSorting direction modifier`sort list descending`
Appendix B

DJVM Bytecode Reference

Detailed mapping of opcodes, stack changes, and execution behaviors in the virtual machine.

The DJVM executes compiled code objects represented as arrays of Instructions. Each instruction contains an Opcode number and a value Argument. The following list documents every opcode in the DJVM v1.0 specification:

### Opcode Mapping Table

Opcode IDInstruction NameArgumentStack BehaviorDescription
**1**`LOAD_CONST`ValuePush `[Value]`Pushes a constant literal onto the stack.
**2**`LOAD_VAR`Variable NamePush `[Variable Value]`Looks up a variable in the environment and pushes its value onto the stack.
**3**`STORE_VAR`Variable NamePop `[Value]`Pops the top of the stack and stores it in the local scope variables map.
**4**`BINARY_OP`Operator NamePop `[Right]`, Pop `[Left]` -> Push `[Result]`Performs an arithmetic or comparison operation on the top two elements and pushes the result.
**5**`UNARY_OP`Operator NamePop `[Value]` -> Push `[Result]`Performs a unary operation (like logical reverse) on the top element and pushes the result.
**6**`DISPLAY`NonePop `[Value]`Pops the top element and prints its string representation to standard output.
**7**`TAKE_PROMPT`Variable NamePop `[Prompt]`Displays prompt, reads user entry as string, and stores it in a variable.
**8**`TAKE`Variable NameNoneReads user entry silently and stores it in a variable.
**9**`JUMP`Instruction IndexNoneSets the Instruction Pointer (IP) to the target index.
**10**`JUMP_IF_FALSE`Instruction IndexPop `[Value]`Pops stack. If falsy, sets the IP to the target index.
**11**`JUMP_IF_TRUE`Instruction IndexPop `[Value]`Pops stack. If truthy, sets the IP to the target index.
**12**`MAKE_FUNCTION`Func DataPush `[Function]`Wraps parameters, name, and bytecode into a function object and pushes it.
**13**`CALL_FUNCTION`Arg CountPop `[Args]`, Pop `[Func]` -> Push `[Return]`Invokes the function with the specified number of arguments, creating a new frame.
**14**`RETURN`NonePop `[Value]`Pops return value, pops the current frame off the call stack, and pushes value to parent stack.
**15**`DUP`NonePush `[Top Value]`Duplicates the top element of the stack.
**16**`POP`NonePop `[Top Value]`Discards the top element of the stack.
Appendix C

Side-by-Side Comparison with Python

Syntactic reference table mapping DJPROCODE features directly to Python code examples.

DJPROCODE and Python are both high-level, human-readable scripting languages. However, they structure blocks and operations differently. The following table provides a direct side-by-side mapping for all common programming tasks:

FeaturePythonDJPROCODE
**Print Output**`print("Hello")``display "Hello"`
**Variable Declaration (Typed)**`x: int = 5``store x as number = 5`
**Variable Declaration (Dynamic)**`x = 5``store x = 5`
**Constant Declaration**`PI = 3.14` *(convention only)*`fixed PI as point = 3.14`
**User Input**`name = input("Enter: ")``take "Enter: " in name`
**Conditional Statement (If)**`if x > 5:``check x big 5`
**Conditional Else**`else:``otherwise`
**Conditional Else-If**`elif x == 5:``otherwise check x same 5`
**Conditional Block End***Indentation changes*`stop`
**Switch Statement**`match val:``choose val`
**Switch Case**`case 1:``case 1`
**Switch Case End***Indentation changes*`stop`
**Loop N Times**`for _ in range(5):``loop 5`
**Range Loop**`for i in range(1, 6):``count i from 1 to 5`
**While Loop**`while not done:``until done same yes`
**Function Definition**`def calc(a, b):``create calc(a, b)`
**Function Call**`calc(5, 10)``open calc(5, 10)`
**Function Return**`return res``send back res`
**List Literal**`[1, 2, 3]``[1, 2, 3]`
**List Indexing**`arr[0]``arr[0]`
**Addition / Concat**`+``plus`
**Subtraction**`-``minus`
**Multiplication**`*``into`
**Division**`/``by`
**Modulo**`%``remain`
**Logical AND**`and``both`
**Logical OR**`or``either`
**Logical NOT**`not``reverse`
**Comments**`# comment``// comment`
**Booleans**`True` / `False``yes` / `no`
**Null Values**`None``nothing`
Appendix D

DJPROCODE Grammar EBNF

Formal Extended Backus-Naur Form grammar specification for the DJPROCODE parser.

The grammatical structure of DJPROCODE v1.0 is formally defined below using Extended Backus-Naur Form (EBNF) notation. This specification guides the parser development in `core/parser.py`.

program = [ "start" ] { statement } [ "stop" ] EOF ;

statement = display_statement

display_statement = "display" expression ;

store_statement = ( "store" | "fixed" ) IDENTIFIER [ "as" KEYWORD ] "=" expression ;

take_statement = "take" [ STRING "in" ] IDENTIFIER ;

check_statement = "check" expression block

{ "otherwise" "check" expression block }

[ "otherwise" block ]

"stop" ;

choose_statement = "choose" IDENTIFIER

{ "case" expression block "stop" }

[ "default" block "stop" ]

"stop" ;

loop_statement = "loop" expression block "stop" ;

until_statement = "until" expression block "stop" ;

count_statement = "count" IDENTIFIER "from" expression "to" expression block "stop" ;

function_declaration= "create" IDENTIFIER "(" [ IDENTIFIER { "," IDENTIFIER } ] ")" block "stop" ;

function_call_stmt = "open" IDENTIFIER "(" [ expression { "," expression } ] ")" ;

return_statement = "send" "back" expression ;

break_statement = "exit" ;

continue_statement = "skip" ;

block = { statement } ;

expression = logical_or ;

logical_or = logical_and { "either" logical_and } ;

logical_and = comparison { "both" comparison } ;

comparison = [ "reverse" ] arithmetic { comparison_op arithmetic } ;

comparison_op = "same" | "notsame" | "big" | "small" | "bigsame" | "smallsame" ;

arithmetic = term { ( "plus" | "minus" ) term } ;

term = factor { ( "into" | "by" | "remain" ) factor } ;

factor = NUMBER

function_call_expr = "open" IDENTIFIER "(" [ expression { "," expression } ] ")" ;

var_or_access = IDENTIFIER { "[" expression "]" | "." IDENTIFIER [ "(" [ expression { "," expression } ] ")" ] } ;