Skip to content

yetnt/jaiva

Repository files navigation

Jaiva!

Version 1.0.1


This esolang of mine is still in development, so expect alot of updates.

Expect : Confusion, Regret, and a bit of fun.

Expect not : A good time, a good language, or a good experience.

To setup, see Install.md To run, see CLI.md

For a list of global variables and functions, see Globals.md

Jaiva files end in the .jiv or .jaiva or .jva extension.

Prerquisuiesdsfb

  1. Get and Install (at least) Java 21 yeah this isn't a good start đź’€ but this shit is amde in java so ye man. Download and install the latest JDK 21

  2. Set Up Jaiva as a Global Command
    Follow the instructions in Install.md to configure Jaiva so you can run the jaiva command from anywhere on your system.

  3. CLI The basic command to run your file is jaiva <filePath> but CLI.md exists.

Index

Screenshots

sc

Syntax

It's simple really, to start off with:

All lines (unless block open and close) must end in an exclamation mark. because why aren't you screaming your code.

maak a <- 10!

Comments.

Single line comments start with an @

@ single line comment

And multi line comments open and close with the { }

{
    wus good shawty
    - stfu
}

Documentation

If you're using something like vscode and would like to document your variables or functions, you can use the following syntax

@* My lovely variable.
maak a <- 10!

Assignment operators

<- Is the basic assignment operator in this language. Any assignment you do is with this.

Note

In the case of defining an array, use <-|

Primitives

Number

This is just any integer or real number

They don't need any special format, you can just type the number out to use it

maak b <- 10!
maak c <- 9.321!

(also scientific notation is supported)

maak b <- 1e4!

Bools

true and false are supported, but so are aowa (maps to false) and yebo (maps to true). because come on now this is just cool.

They don't need any special format, you can just type the bool out to use it

maak b <- aowa!

Strings

Strings, stolen striaght from Java use " (double quotes) to start and end a string.

These are the only characters for strings. No string literals or multi line strings because wtf dawg.

maak b <- "String"!

To get the length of a string use the ~ operator

maak b <- "let's gooo"!
khuluma(b~)! @ returns 10
String operations.
  1. Concatenation

    "a" + "string" returns "astring"

    1 + "string" returns "1string"

    "string" + 1 returns "string1"

  2. Substring (first occurance)

    "string" - "tri" returns "sing" (removes the first occuramce of rhs from the lhs. Sometimes this dont work tho lol.)

    "string" - 2 returns "stri"

    2 - "string" returns "ring"

  3. Multiplication

    "String" * 3 returns "StringStringString"

  4. Substring (all occurances)

    "remove all es please" / "e" returns "rmov all s plas" (removes ALL occurences of rhs from the lhs. Sometimes this dont work too lol.)

    "Hello ong World" / 2 returns "Hello o" (returns the substring in the range [0, (lhs' length)/rhs) )

    4 / "Hello ong World" returns "lo ong World" (returns the substring in the range [(rhs' length)/lhs, rhs.length-1) )

    And of course, you can compare strings to each other using = and !=

  5. Contains

    "string" ? "tri" returns true (checks if the left-hand string contains the right-hand string)

    "string" ? "xyz" returns false

Escaping characters

To escape characters in a string use the $ symbol.

maak b <- "String$n"!

Table of escape characters

character escape sequence
= $=
, $,
! $!
@ $@
\n (new line) $n
\t (tab) $t
\r (carriage return) $r
\b (backspace) $b
\f (form feed) $f
" (double qoutes) $"
$ $$

idk

This is a primitive which is used to represent nothingness.

maak a <- idk!
maak b!
maak c <- 10!

khuluma(a = idk)! @ true
khuluma(b = idk)! @ true
khuluma(c != idk)! @ true

Note

In the case of passing idk into a function call, unless the paramter is marked as optional, you cannot pass idk into a required parameter.

Arithmatic and Boolean Comparisons

operation operator
modulu %
division /
multiplication *
addition +
subtraction -
unary minus -
is equal to (not double equals) =
is not equal to !=
greater than (and equal to) > >=
less than (and equal to) < <=
braces for ordering ( )

Note

You cannot negate an expression. Sorry not sorry.

Blocks

Blocks are defined by the -> and <~ symbols. The -> symbol opens a block, and the <~ symbol closes it.

I think this is where jaiva deviates from normal programming languages, Especially since your usual { } is reserved for comments.

Note

You can have multiple blocks in a single line, but this is not recommended. It makes the code hard to read. (And i dont think i implemented or tested that case.)

Note

You can only have a block after like, an if, or a function and whatever, you cant just open an new arbitrary block in the middle of your code. This is a design choice, and i think it makes sense.

if (a = 10) ->
   @ inner code
<~

Keywords

Alot of the keywords refer to words from south african languages, so if you happen to know one, you've got the advantage here's a cheat table though

keyword meaning and what it's assigned to language origin
maak make/new (variable declaration keyword) Afrikaans
aowa no (false) Sepedi
yebo yes (true) Zulu
khuluma talk (print to console) Zulu
mara but (else block) Sesotho
kwenza does (defines a function) Zulu
khutla return (function return keyword) Zulu
colonize for (for loop) English
zama zama try (try block) Zulu
cima turn off (throw) Zulu
chaai "oh no!" or "oh shit!" (catch block) idk
voetsek "fuck off" (break keyword) Afrikaans
nevermind Self-Explanatory (continue keyword) English
with keyword used to define for each loop along with colonize English
tsea import from another file Sepedi

Variables

Variables are scoped constructs.

See Globals for a list of global variables that are available to you.

Definition

maak (variable name) <- (value)!

Simple asf

maak a <- 20!           @ number
maak var1 <- "string"!  @ string
maak var5 <- aowa!      @ boolean
maak f!                 @ define without a value.

Also a neat feature, since only a specifc set of chars are reserved, this allows for some weird variable names that is allowed.

Statement Variable Name
maak a b <- 10! a b
maak a b <- 100! (diferent from above) a b
maak #b... <- 20! #b...
maak \ <- 10! \

And more crazy combos you can come up with. if it doesnt result in a generic Java error, it's probably valid. Go wild.

Use

maak a <- 20!
maak b <- 10!
maak c <- a + b! @ 30

Reassignment

maak a <- 20!

a <- 10!
a <- "string"!

You can reassign any type really. This shit aint type safe.

Arrays

Arrays are 0-indexed. This isn't Lua afterall

maak a <-| 20, 23, 56, 324, 354!
maak b <-|! @ Empty array.

Yknow. Then you can access elements of the array using the [] operator.

maak a <-| 20, 23, 56, 324, 354!
maak b <- a[0]! @ 20

To get the length of an array use the ~ operator.

maak a <-| 10, 23, 984!
khuluma(a~)! @ returns 3

Functions

Functions are scoped constructs.

See Globals for a list of global functions that are available to you.

Defintion

Functions are defined using the kwenza keyword, and return values using the khutla keyword.

kwenza addition(param1, param2) ->
    khutla (param1 + param2)!
<~

Calling

Just like any other language, you can call a function by just using the name of the function and passing in the parameters.

maak a <- 10!
maak b <- 20!
maak c <- addition(a, b)! @ 30
@ or
maak c <- addition(10, 20)! @ 30

Function parameters can take any type of variable, including arrays and other functions.

Parameters

Higher-Order Functions

In the case wehere you want to pass a function into another function, you will have to input F~ to the name of the parameter to explicity tell the interpreter that the shi u finna input should be treated as a function.

V~ is available for variables, but its not needed as without this typing, its always assumed to be a variable

kwenza function(F~ref) ->
    khutla ref()!
<~

kwenza returnNum() ->
    khutla 100!
<~

khuluma(function(returnNum))! @ prints 10

be careful when you start doing this though as when you start calling and chaining these, you loose variables in scopes since it doesnt know an shi.

Optional Arguments

In the case where you need certain arguments to be optional, stolen straight from typescript, all you gotta do is suffix the parameter name with ? then it will not be required when calling the function.

kwenza function(param?) ->
    khuluma(param = idk)! @ When a parameter is optional and it is not given,
                           @ It will be set to the type idk
<~

function()! @ prints true
function(10)! @ prints false

Warning

When a parameter is required, it CANNOT be set to idk or be empty in the parameters list of the function call. That's the whole point of a required parameter, that it is a value.

If Statements

For if statements, if is the keyword, and mara is the else statement.

Basic If

if (condition) ->
    @ block to execute.
<~
maak variable <- 10!
if (variable != 100) ->
    khuluma("Variable isn't 100")!
<~

mara (else)

if (condition) ->
    @ block to execute
<~ mara ->
    @ block to execute if the condition is false
<~
if (variable != 100) ->
    khuluma("Variable is not 100")!
<~ mara ->
    khuluma("It's 10")!
<~

Warning

You cannot put the mara keyword underneath the end of an if block, it HAS to be on the same line as the closing <~ symbol. This makes it easier for me lol.

mara (else) with if

if (condition) ->
    @ block to execute
<~ mara if (condition) ->
    @ another block.
<~
maak variable <- 10!
if (variable != 100) ->
    khuluma("Variable is not 100")!
<~ mara if (variable = 10) ->
    khuluma("Variable is 10")!
<~

You can chain as many mara if statements as you want, but this is not recommended. (It makes the code hard to read, and this language is already hard enough to read)

You can also nest if statements. because why not.

Warning

You can use a normal mara block along with other mara if blocks. However the mara block must be the LAST block of the entire if chain.

Loops

Nikhil loops (while loops)

Shoutout to Nikhil for this one.

Twitter Instagram
YouTube @nikhil17 (probably idk)
Discord @Nikx17

nikhil (condition) ->
    @ block to execute
<~

Where

condition is the condition to check for the loop to continue. This is a boolean expression.

Colonize loops (for loops)

This ones a bit weird.

colonize (variable init) | (condition) | (increment) ->
    @ block to execute
<~

Where

variable init is the variable to use in the for loop, and the initial value.

condition is the condition to check for the loop to continue. This is a boolean expression.

increment is the increment to use for the loop. This can be a + or a - sign.

and the | is the separator between the three parts of the for loop.

colonize i <- 0 | i <= 10 | + ->
    khuluma(i)! @ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
<~

colonize with (for each)

colonize (variable name) with (array) ->
    @ block
<~

Where

variable name is the variable to use in the for loop, and the initial value.

array is the array to loop through.

colonize word with reservedKeywords ->
    khuluma(word)! @ prints all the reserved keywords
<~

Control flow

For all loops, to forcefully exit a loop, use the voetsek keyword.

nikhil (a = 10) ->
    khuluma(a)! @ 10
    voetsek! @ this will break out of the loop, stopping it.
<~

To skip to the next iteration of a loop, use the nevermind keyword.

colonize i <- 0 | i <= 10 | + ->
    if (i = 5) ->
        nevermind! @ this will skip the rest of the loop and go to the next iteration.
    <~
    khuluma(i)! @ 0, 1, 2, 3, 4, 6, 7, 8, 9, 10
<~

Error handling

Jaiva has error handling and throwing! This is done using 2 constructs.

Throw an error

Use the cima keyword follwed by the <== operator, then followed by the error message.

<== is the assignment operator for errors. Literally not used anywhere else but for this.

cima <== (error message)!
maak a <- 10!
if (a = 10) ->
    khuluma("a is 10")!
<~ mara ->
    cima <== "a is not 10"! @ this will throw an error.
<~

zama zama (try) chaai (catch) block

The zama zama keyword (both, one zama won't work.) is used to define a try block, and the chaai keyword is used to define a catch block.

The chaai block is executed if an error is thrown in the zama zama block.

Note

When in a chaai block, you have access to a special variable called

Warning

You cannot have a zama zama block without a chaai block. This is a design choice, and it makes sense.

Warning

You cannot put the chaai keyword underneath the end of a zama zama block, it HAS to be on the same line as the closing <~ symbol. This makes it easier for me lol.

zama zama ->
    @ block of code to try
<~ chaai ->
    @ block of code to execute if an error is thrown
<~
zama zama ->
    khuluma(true + 1)!
<~ chaai ->
    khuluma(error)! @ error is a special variable which holds the error message.
<~

Scopes

Everytime you open a block, you create a new scope. This means that any variables or functions you define in that block are not accessible outside of that block.

maak a <- 10!
maak b <- 20!
maak c <- 30!

if (a = 10) ->
    maak d <- 40!
    khuluma(d)! @ 40
    kwenza addition(param1, param2) ->
        khuluma(param1 + param2)!
    <~
<~ mara ->
    khuluma(d)! @ This will error, because d isn't defined in this scope.
    khuluma(a)! @ 10. This works because a is defined in the global scope.
<~

addition(10, 20)! @ Will also error, because addition() is not defined in this scope.

Tsea (import) and exporting files

Importing isn't that bad. Here's a simple import.

Say you have "file.jiv" with the following code.

maak *a <- 10! @ Pre-pend * to the variable name to mark it as a exported variable.
kwenza *addition(param1, param2) -> @ Pre-pend * to the function name to mark it as a exported function.
    khuluma(param1 + param2)!
<~

@ Note: Using the variables/functions are still normal. When using them you don't have to prepend the * to them. It's just simply a marker for the tokenizer to know that this variable/function is exported.

Then in your main file, you can import it like this.

tsea "file.jiv"! @ or you can have an absolute import.
khuluma(addition(a, 1))! @ 11

Or if you want to import a specific variable or function, you can do this.

tsea "file.jiv" <- addition!

Note

File paths are relative to the current working directory. So if you have a file in a different directory, you will have to use the full path to the file.

Note

You can also import files from the Jaiva library. Example to import the arrays files

tsea "jaiva/arrays"!

See Globals for a list of global variables and functions that are available to you, and others that you can import.

Note

Omitting the file extension is okay, however it will default to .jiv