How it works
Runtime and Types
Every value in a running kemlang-py program is one of five Python types. This page covers how those types behave, how coercion works, what is truthy, and the full lifecycle of a program from file read to process exit.
KemValue - the runtime type
kemlang/types.py
KemValue = int | float | str | bool | None # There are no wrapper classes. Python's built-in types ARE the runtime types. # int -> 42, 0, -7 # float -> 3.14, 0.5 # str -> "hello", result of bapu tame bolo # bool -> bhai chhe (True), bhai nathi (False) # None -> result of failed input coercion
typekemlang-py literalnotes
int42, 0, -7arbitrary precision Python intfloat3.14, 0.5, -1.0IEEE 754 double, same as Python floatstr"hello"UTF-8, double-quoted, single-line onlyboolbhai chhe / bhai nathiPython True/False (subclass of int)None(no literal)failed input coercion; never user-writableDynamic typing
Variables have no declared type. They hold whatever value was assigned to them, and that type can change on reassignment. The interpreter discovers the type of a value at runtime using Python's isinstance().
valid in kemlang-py
kem bhai aa x che 42 # x is int x che "hello" # x is now str - perfectly legal x che bhai chhe # x is now bool aavjo bhai
Truthiness
Conditions accept any KemValue. The interpreter applies the same rules as Python's bool():
valuetruthy?notes
bhai chheyescanonical truthy valuebhai nathinocanonical falsy valueany non-zero intyes0 is falsy; 1, -5, 42 are truthy0nozero integerany non-zero floatyes0.0 is falsy0.0nozero floatnon-empty stringyes"hello", "0", " " are all truthy""noempty stringNonenoalways falsyArithmetic and type promotion
arithmetic type rules
int op int -> int 5 + 3 = 8
int op float -> float 5 + 3.0 = 8.0
float op float -> float 1.5 * 2.0 = 3.0
Division: 7 / 2 uses Python / -> 3.5 (float, not integer 3)
Modulo: 7 % 3 -> 1
Negation: -5 -> int
-3.14 -> floatThe + operator
If either operand is a string, both are stringified and concatenated. Otherwise, numeric addition is performed.
+ operator coercion examples
10 + 5 -> 15 numeric addition
10 + 3.14 -> 13.14 int + float promotion
"score: " + 10 -> "score: 10" str on left -> stringify right
10 + " points" -> "10 points" str on right -> stringify left
"a" + "b" -> "ab" both str -> concatenate
stringify() rules:
int: str(n) -> "42"
float: str(f) -> "3.14"
bool: True -> "bhai chhe" False -> "bhai nathi"
None: "none"kemlang/interpreter.py - + operator implementation
if op == TokenType.PLUS:
if isinstance(left, str) or isinstance(right, str):
return self.stringify(left) + self.stringify(right)
return left + rightComparison operators
comparison examples
10 == 10 -> bhai chhe (True) 10 == 10.0 -> bhai chhe (True - int/float equality in Python) 10 == "10" -> bhai nathi (False - different types) "a" < "b" -> bhai chhe (True - lexicographic) bhai chhe == 1 -> bhai chhe (True - bool is int subclass, True == 1) bhai nathi == 0 -> bhai chhe (True - False == 0 in Python)
Full execution lifecycle
from kem run to process exit
Error propagation
error typewhen raised
LexerErrorBad character in source. Raised immediately - no parsing or execution.ParseErrorGrammar violation in token stream. Raised immediately - no execution.RuntimeErrorBad operation during execution. Caught at interpret() top level, prints message, returns exit code 1.