Skip to content

Grammar

This chapter explains the overall structure of EasyLang programs:
how statements are arranged, how blocks work, how expressions are formed, and how the interpreter reads your code.

This is not a strict compiler-level grammar — instead, it’s a simple, clear description of how EasyLang actually behaves according to the parser implementation.


Program Structure

An EasyLang program is simply a sequence of statements:

program = statement

Statements execute top to bottom unless controlled by loops or conditions.

Example:

we let x = 10
so print x

There are no semicolons or indentation rules — EasyLang uses newlines and brackets to group code.


Blocks

Blocks of code appear inside [ … ] brackets.

Example:

if x greater 10 then [
    so print "big"
]

Blocks may contain any number of statements, even nested blocks:

repeat while x less 5: do [
    if x equals 2 then [
        so print "halfway"
    ]
    we let x = x plus 1
]

Brackets are required for multi-line bodies, but may be optional for single-line expressions depending on context.


Statements (Top-Level Grammar)

EasyLang supports these major statement forms:

statement =
      assignment
    | print_statement
    | if_statement
    | repeat_loop
    | function_definition
    | return_statement
    | bring_statement
    | file_open
    | file_write
    | file_read
    | continue_statement
    | break_statement
    | expression_call

Each one is explained in more detail in Statements.


Assignment Grammar

EasyLang uses English-like assignment:

we let IDENTIFIER = expression

Examples:

we let x = 10
we let name = "John Doe"
Reassignments also work:
we let x = x plus 1

The interpreter evaluates the right-hand side first, then stores the value.


Print Grammar

Printing uses:

so print expression

Examples:

so print "Hello"
so print x plus 2


If / Else Grammar

The grammar structure:

if expression then block
    (else if expression then block)*
    (else block)?

Example:

if x equals 10 then [
    so print "ten"
] else if x greater 10 then [
    so print "big"
] else [
    so print "small"
]

Each branch must contain a block.


Loop Grammar

Repeat-While Loop

repeat while expression: do block

Example:

repeat while x less 10: do [
    so print x
    we let x = x plus 1
]

Repeat-From Loop (Counter Loop)

repeat from IDENT = start_expr to end_expr: do block

Example:

repeat from i = 1 to 5: do [
    so print i
]


Function Definition Grammar

Functions are defined like:

define name(args...): do block

Example:

define add(a, b): do [
    return a plus b
]

Argument structure:

arglist = (IDENTIFIER (',' IDENTIFIER)*)?

Functions always return a value using: return expression

If return is missing, the function returns null (Python None).


Function Call Grammar

Calls follow this pattern: expression '(' arguments ')'

Arguments are comma-separated: call(a, b, 10, "name")

EasyLang also supports method calls using dot notation:

list.push(5)
user.name.upper()


Module Import Grammar

Modules can be brought into the program using: bring IDENTIFIER as IDENTIFIER

or by file path: bring "math.elangh" as math

Examples:

bring math as m
m.sqrt(25)

bring "strings.elangh" as str
so print str.upper("hello")

Python modules are wrapped into EasyLang-accessible objects.


File I/O Grammar

Opening a file: open STRING as IDENTIFIER for (read | write | append)

Writing: writeline IDENT with expression

Reading: readline IDENT into IDENT

Closing: close IDENT

Example:

open "out.txt" as f for write
    writeline f with "Hello!"
close f


Expression Grammar (Overview)

The full details are in Expressions, but a simplified version is:

expression =
      literal
    | IDENTIFIER
    | list_literal
    | dict_literal
    | unary_op expression
    | expression binary_op expression
    | expression '(' arguments ')'
    | expression '.' IDENTIFIER


Literals

Supported literals:

NUMBER
STRING
true
false
[ list items... ]
{ "key": value, ... }

Examples:

10
"hello"
true
[1, 2, 3]
{"name": "GreenBugX", "age": 16}


Operator Precedence (Simplified)

From highest to lowest:

  • Parentheses ( )
  • Method calls obj.method()
  • Multiplication / Division
  • Addition / Subtraction
  • Comparisons (equals, <, >, etc.)
  • Logical AND
  • Logical OR

EasyLang enforces this through the recursive descent parser.


Grammar Summary (Simplified EBNF)

This is a readable EBNF-style summary:

program        = statement* ;

statement      = assignment
               | print
               | if
               | repeat_while
               | repeat_from
               | define
               | return
               | bring
               | file_ops
               | break
               | continue
               | expr_call ;

assignment     = "we let" IDENT "=" expression ;
print          = "so print" expression ;

if             = "if" expression "then" block
                 ("else if" expression "then" block)*
                 ("else" block)? ;

repeat_while   = "repeat while" expression ":" "do" block ;
repeat_from    = "repeat from" IDENT "=" expr "to" expr ":" "do" block ;

define         = "define" IDENT "(" arglist ")" ":" "do" block ;
arglist        = (IDENT ("," IDENT)*)? ;
return         = "return" expression ;

bring          = "bring" (STRING | IDENT) "as" IDENT ;

file_ops       = "open" STRING "as" IDENT "for" mode
               | "writeline" IDENT "with" expression
               | "readline" IDENT "into" IDENT
               | "close" IDENT ;

block          = "[" statement* "]" ;

expression     = logical_or ;


Next Steps

Continue to Statements to learn how statements work in detail