+
Skip to content

yetnt/jaiva

Repository files navigation

Jaiva!

(Current) Version : 1.0.2

(Beta) Version : 2.0.0-beta.2

isTen

screenshot of the testType.jiv program


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

This is for the most part supposed to be a functional programming language.

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

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.

Accept for arrays, thats specifically <-| (See Arrays)

And also for throwing errors, thats <== (See Throw an error)

Types

In terms of actual types, Jaiva doesnt have type syntax like Java or Typescript. This is a loosely typed language. However some functions do error when you do not provide the correct type, so keep that in mind.

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! @ This gets parsed as 10000

even binary, hex and octal notation is supported! (it always gets parsed as an integer)

maak c <- 0b1010    @ Integer 10 in binary
maak d <- 0xA       @ Integer 10 in hexadecimal
maak e <- 0c12      @ Integer 10 in Octal

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 constant and value which is used to represent nothingness.

maak a <- idk!  @ Using idk as a value
maak b!         @ Creating a variable with no value assigns idk to it
maak c <- 10!

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

kwenza func(t?) ->
    khutla t!
<-

khuluma(func())! @ Prints idk, as the parameter t did not get a value.

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.

Operators

operation operator
modulu %
power ^
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) < <=
logical AND &&
logical OR ||
Logical NOT (Negation) '
bitwise AND &
bitwise OR |
braces for ordering ( )
bitshift left <<
bitshift right >>
hexshift left <x
hexshift right >x

Note

Where other languages use ! as logical NOT as a prefix to the expression. Jaiva uses ' as a logical NOT as a postfix expression. Where a normal language would right !(var != 3) in Jaiva the equivalent is (var != 3)'

Order of Operations

All Operations follow this exact order:

  1. Exponentiation (Highest precedence)
  2. Division, Multiplcation, Modulo
  3. Addition, Subtraction
  4. Bit/Hex Shifts
  5. Bitwise Operators
  6. Comparisons
  7. Logical Operators (Lowest precedence)

Use (braces) to change the order however you wish.

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, ur crazy if u think im finna allow that )

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
<~

Chaining

In Jaiva you have array indexing with [] (See Arrays) and function calling with () (See Functions)

Naturally, you can make some code like this:

kwenza returnArray() ->
    maak arr <-| 10, 39, returnArray, 4!    @ Creates an array with values and at index 2, contains a reference to itself.
    khutla arr!
<~

Instead of assigning each value returned to a variable, you can chain array indexing and function calls together, multiple times, in any order or any fashion

returnArray()[1]!               @ holds 39
returnArray()[1 + 1]!           @ ([1+1] becomes [2]) holds the referencing to itself, allowing it to call itself.
returnArray()[-1 + 3]()!        @ ([-1+3] becomes [2]) returns the same array.
returnArray()[2]()[4/2]!        @ ([4/2] becomes [2]) holds the exact same reference to itself, allowing infinite calls to itself

@ holds the exact same reference, every time.
returnArray()[2]()[2]()[2]()[2]()[2]()[2]()[2]()[2]!

One of my favourite examples is the infinity function

kwenza infinity() ->
    khutla infinity!
<~

infinity()!             @ Returns itself
infinity()()()()!       @ Returns itself
infinity()()()()()()()()()()()()()()()()()()()()()()! @ Still returns itself.

Jaiva's Interpreter however will take a while to resolve this mess of code when the chaining gets absurdly long. But if you give it time it will work.

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 use in jaiva language origin reference
maak "make" variable declaration keyword Afrikaans Variables
aowa "no" false Sepedi Bools
yebo "yes" true Zulu Bools
if - conditional execution keyword English If Statements
mara "but" keyword to start an else block Sesotho Mara (else)
kwenza "does" function definition keyword Zulu Functions
khutla "return" function return keyword Zulu Functions
colonize - loop constructs (for loop and for-each loop) English Colonize loops
nikhil - while loop keyword it's a name, not sure Colonize loops
zama zama "try" try block Zulu (informal?) Errror Handling
cima "turn off" keyword to throw an error Zulu Throw an error
chaai "oh no" (subjective meaning) catch block lowkey dont know Error Handling
voetsek "fuck off" break keyword Afrikaans Control flow
nevermind - continue keyword English Control flow
with - keyword used to define for each loop along with colonize English Colonize loops
tsea "take" keyword to import symbols from another file Sepedi Tsea
idk - This is a special keyword, as it also acts as a value. (null) English idk
however - (else keyword in a ternary) English Ternary ifs

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

Array literals do not exist. Sorry not sorry.

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.

Referencing

You can reference a function by excluding the parameter braces.

khuluma(additon)! @ This will print to the console, the function's defintion. So "addition(param1, param2)"

And you can pass this reference as a value anywhere you want really

(See Higher-Order Functions for passing function references in other functions)

maak new <- addition!   @ This will mkae the variable new hold the reference to the function addition
khuluma(new(10, 10))!   @ Now new can be used as a function, and will act exactly like addition
khuluma(new)!           @ Printing new will give you the original function's declaration so "addition(param1, param2)"

And some more funky examples

kwenza anotherFunc() ->
    khutla 10!
<-

maak t <- anotherFunc!  @ This assigns t, the reference to anotherFunc
anotherFunc <- khuluma! @ This reassigns anotherFunc as a reference to khuluma

khuluma(t)!             @ Print "anotherFunc()"
khuluma(t())!           @ Prints 10
khuluma(anotherFunc)    @ Prints "khuluma(msg, removeNewLn?)"
anotherFunc("hello")!   @ Prints "hello" (Since this is just khuluma.)

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")!
<~

Note

Other languages allow you to put a variable as a the condition to check for truthiness. We don't allow that here, check it against true or idk

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.

Ternary Ifs

This is your shorthand one line if statement that returns a value too.

This is the syntax

(condition) => (expression1) however (expression2)

Where if (condition) returns true, it returns (expression1) however if not, return (expression2).

(With or without braces)

(Yes including the however keyword)

So you can do things like

maak control!
@* braces are added to make it more readable, you don't need them
maak a <- ((control = idk) => idk however 0xFFFF)!

Where if the variable control is idk , thne variable a will be set to idk too. Otherwise, it will be set to the integer 0xFFFF

And you can chain them

maak input <- mamela("enter a number")! @ Waits for number input fom the console.

kwenza clamp(number, min, max) ->
    khutla (number > max => max however (number < min => min however number))!
<~

khuluma(clamp(input, 0, 50))!

Here we define a function clamp which will... clamp, what'd you think, the given number to the given minimum value and maximum value.

Note

While it's not required to have braces around the expressions or condition. Just have them you maniac.

Warning

You cant have ternaries on new lines, they hve to be in the sam eline if you chain them unfortunately

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 variable

When in a chaai block, Jaiva gives you access to a variable named "error" which holds the error that ocurred in string form however if there already is a variable named error, it will increment the new error variable by 1.

zama zama ->
    khuluma(idk - 1)! @ throws error
<~ chaai ->
    zama zama ->
        khuluma("an error bruh" - idk)! @ another error
    <~ chaai ->
        khuluma(error)!     @ This is the (idk - 1) error
        khuluma(error1)!    @ This is this context's error (So the ("an error bruh" - idk) error)
    <~
<~

Note

The way the code works, is it looks in it's current context for any variable which contains the exact word "error", so if you have like 4 variables named error, and you decide to open a chaai block, the name of the error variable will be "error4" (it counts the amount of current variables named error, and adds it to the variable name) Just keep this in mind This is defined in Interpreter.java on line 499

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

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载