Zen++ banner

Zen++

6 devlogs
15h 53m 10s

A programming language built just to my liking :)
Interpreter written in C++
Great for competitive programming (USACO / codeforces) because of the syntax

Zain Marshall

Zen++ Devlog VI

This was a pretty big update but I didn’t add anything that is syntaxically weird. I added functions, vectors, and strings.

What changed:

  1. Functions + Returns

    • Added parsing/eval support for fn name(args){...} and return expr.
    • Added scope
    • Added built-in functions like read() and print()
  2. Strings

    • Strings are defined with "string"
    • Can store/print/concatenate strings.
    • You can index into strings (s[i]) and use len(s).
  3. Vectors (Dynamic Arrays)

    • Added vector syntax: [1, 2, 3].
    • Added vector indexing: v[i].
    • Added built-ins:
      • len(v)
      • push(v, x)
      • pop(v)
    • Added vector concatenation
  4. Multidimensional vectors

    • Because vectors can contain vectors, nested structures like [[1,2],[3,4]] just work.
    • Nested indexing works (m[1][0]).
  5. Comments + Illegal Character Throwing

    • Added support for comments like // or /* ... */
    • Added stricter behavior for unknown/invalid characters so bad input doesn’t silently pass.
  6. Reorganization

    • src/ has source code
    • test/ has tests
    • build/ now contains the compiled binaries
    • docs/ contains docs/devlogs.
  7. Makefile + Testing

    • Added a Makefile with nice commands
    • make run launches REPL.
    • make run <file.zpp> runs a file directly.
    • Made test.zpp as a file with every command in the language and then wrote the expected output and made make test run the test script and compare output.

Changelog

Attachment
0
Zain Marshall

Zen++ Devlog V

Ok so in this devlog I spent a lot of time thinking about syntax and I would like some feedback about for loops.
First though, while loops were simple (not simple to implement these loops cooked me in coding but syntaxically simple), its just.

while boolean {
do this code here yeah
}

So while loops are very simple. Now for loops were a pain. I wanted them to be simple as this is meant to be super fast to write for competitive programming and the likes. So for this I took inspiration from my C++ template file.

#define FOR(i, a) for(int i = 0; i < a; i++)
#define ROF(i, a) for(int i = a; i >= 0; i--)
#define FORA(i, a, b) for(int i = a; i <= b; i++)
#define ROFA(i, a, b) for(int i = a; i >= b; i--)

That’s how I macro for loops during Codeforces contests. So instead of
for(int i=0;i<n;i++){...} I can just do FOR(i,n). Now I wanted something nice and simple for Zen++ to. So I landed on this:
A four loop has four components, the variable used, the start, the end, and the step. So why not instead of writing those as a declaration, a boolean, and an incrementation like in C++, just treat those almost as paramateres to a method. So thats what I did.
for i start end step {...}
Thats the syntax. If you want a reverse for loop you just make end bigger than start and step will be negative.
There is a 3-arg version which defaults step to 1 or -1 depending on direction and looks like: for i start end{...} and there is a 2-arg one which is: for i end{...} and defaults step to +1 and start to 0. So for codeforces you can just write for i n{...}. Very simple, but leave comments if you think its ugly. Its exclusive by default rn with no way to make it inclusive, I’ll fix that later.

Changelog

Attachment
Attachment
0
Zain Marshall

Zen++ Devlog IV

I added if else statments to the code! The way an if else-if else statment will be written is like tihs:

if bool1{
    x=1
}else if bool2{
    x=2
}else{
    x=3
}

Note the lack of parantehsis, you don’t rly need them beacuse you know your condition is just gonna be sandwiched between the if and the next curly brace. Also now that I added braces I made the parser handle the braces and the AST handle blocks of code.

What changed:

  1. The lexer recognizes if, else, { and }.
  2. The parser builds block nodes and full if/else chains, and parses the full program instead of a single statement.
  3. The evaluator now runs blocks and if/else nodes.
  4. The REPL buffers lines and runs the program when you submit a blank line.

Changelog

Attachment
0
Zain Marshall

Zen++ Devlog III

This step adds booleans and comparisons so I can start building if/else statements later. Booleans are just like they are in C++, a true boolean is a 1 and a false boolean is a 0.

What changed:

  1. The lexer now recognizes true/false and multi-character operators like ==, !=, <=, >=.
  2. The AST got boolean literals, comparison operators, and logical NOT.
  3. The parser now handles comparison expressions and prefix !, while keeping postfix ! for factorial.
  4. The evaluator now returns 0/1 for comparisons and supports logical NOT.

Changelog

Attachment
0
Zain Marshall

Zen++ Devlog II

I added variables and assignment. You can declare a variable like x=4 and reassign it like x=5

What changed:

  1. The lexer now recognizes identifiers and the = token
  2. The AST supports variable nodes and assignment nodes.
  3. The parser now uses a lookahead to treat identifier = expr as an assignment, and it also lets identifiers show up inside normal expressions.
  4. The evaluator keeps a small variable map so assignments store values and identifiers read them back.

Changelog

Attachment
0
Zain Marshall

Zen++ Devlog I

So I did a few things:

  1. I decided on the syntax of Zen++. Since I want to use it for like codeforces and stuff it should be very fast to type out while still being fast. So I decided on the syntax of the language. It will use curly braces to delineate blocks of code, no semicolons, for variables no let keyword and optional type so like x=1 for now. For loops and if statements no need for parentheses, just do while tc– or if bool. See idea.md for more.
  2. I decided it’ll be interpreted and I got started on basic math. So the way it works is you start with the statement in code, then a lexer tokenizes it (it identifies what is a parenthesis what is a plus sign, stuff like that), and then a parser takes the tokens and creates a hierarchy (so like pemdas) by making an Abstract Syntax Tree which we then evaluate by going to the bottom nodes, evaluating them and then propagating upwards. So very cool things. So far I just did basic binary arithmetic operations like + - * / % ^ and also a unary operator !. The code is made so its decently easy to add more tokens.

Changelog

Attachment
0