This document provides a comprehensive specification of the Layman programming language grammar. It reflects the current implementation where code is written in pure English, minimizing special characters and punctuation.
Layman uses a natural language lexer. The code is tokenized into words, numbers, strings, and standard punctuation.
- Line Comments: Start with
#and continue to the end of the line.
- Variable and function names are typically lower_case or snake_case identifiers.
- Multi-word names in variable declarations (e.g.,
user name) are treated as distinct words but generally parsed as single identifiers in practice.
- Numbers:
123,3.14,-5 - Strings:
"Hello world",'Single quoted',"""Multi-line strings""" - Booleans:
true,false
Key reserved words include:
define, function, variable, if, then, else, while, for, each, in, return, call, with, is, not, and, or, plus, minus, times, divided by, import, expect, test, describe.
A Layman program consists of a sequence of statements.
Program ::= Statement*Statements are the building blocks of execution.
the variable <name> is <expression>
define variable <name> as <expression>
Example: the variable count is 10
the constant <name> is <expression>
Example: the constant pi is 3.14
set <name> to <expression>
<name> is <expression>
Example: set count to 20
define function <name> that takes <param1> and <param2> ... and returns <Type>
<body statements>
Example:
define function add that takes a and b and returns Number
return a plus b
define class <Name> with
property <propName> using <Type>
method <methodName> that takes ... and returns <Type>
<body>
if <condition> then
<statements>
else if <condition> then
<statements>
else
<statements>
end if
for each <item> in <collection> do
<statements>
end for
while <condition> do
<statements>
end while
repeat <count> times
<statements>
end repeat
Expressions evaluate to a value.
Layman strictly enforces English syntax for calls. Parentheses () are not used for invocation.
Syntax:
call <function_name> with <arg1>, <arg2>...
call <method_name> on <object> with <arg1>...
Examples:
call print with "Hello"call assert_eq with result, 10call add on list with item
Properties can be accessed using dot notation or natural language possessives (in future). Currently supported:
<object>.<property>
Special Properties:
list.size,list.length,list.count-> Numberdictionary.size-> Number
Layman supports both symbols and English keywords for operations.
| Operation | Keyword | Symbol |
|---|---|---|
| Add | plus |
+ |
| Subtract | minus |
- |
| Multiply | times |
* |
| Divide | divided by |
/ |
| Modulo | modulo |
% |
| Equals | is, equals |
==, = |
| Not Equal | is not |
!= |
| Greater | greater than |
> |
| Less | less than |
< |
| And | and |
&& |
| Or | or |
` |
| Not | not |
! |
Example: if x is not 10 then...
Layman supports high-level concurrency primitives.
Run a block or function asynchronously.
background
<statements>
end background
Wait for all background tasks to complete.
wait
Execute multiple statements in parallel and wait for all to finish.
concurrently
<stmt1>
<stmt2>
end concurrently
Raise an exception.
throw <expression>
Example: throw "Invalid input"
Handle exceptions.
try
<statements>
catch error
<statements>
end try
Built-in testing keywords facilitate test-driven development.
describe "Feature Name"
test "Scenario 1"
<statements>
end test
end describe
Assertions are performed using standard function calls like call assert_eq with actual, expected.
- Literal:
[1, 2, 3] - Access:
list[0] - Properties:
list.size
- Literal:
{ "key": "value" } - Access:
dict["key"] - Properties:
dict.size
Layman is statically typed but supports inference.
NumberString/TextBool/BooleanVoidList<Type>Dictionary<KeyType, ValueType>Any(dynamic fallback)