Welcome to Phi, a high-level, statically typed, object-oriented scripting language specifically designed to deploy programs quick.
If you encounter any unexpected behavior while using Phi, please report it promptly. Include a screenshot and a detailed description to help us improve and fix.
The following keywords are reserved in the Phi programming language:
int
- Declare an integerreal
- Declare a floating-point numberstr
- Declare a string valuebool
- Declare a boolean valueobj
- Declare an object valuearray
- Declare an array valuelambda
- Used to assign a functionunknown
- Used when the data type is unknownif
- Conditional statementelse
- Else clause for conditional statementswhile
- While loopsdo
- Part of do-while loopfn
- Declare a new functionimport
- Import a moduleexport
- Export a valuebreak
- Terminates the loop. Works for while loop, do while loop and for loopcontinue
- Skips to the next iteration of the loop- All other built-in functions and methods are also reserved words.
Comments start with #
symbol and continue until end of line.
The following operators are supported in Phi:
=
Assignment operator+
Addition-
Subtraction*
Multiplication/
Division (integer division)%
Modulus//
Floor division^
Exponentiation>
Greater than<
Less than>=
Greater than or equal to<=
Less than or equal to==
Equal to!=
Not equal to&
Logical AND|
Logical OR.
Member access+=
Increment-=
Decrement*=
Multiply by/=
Divide by%=
Remainder after dividing by^=
Exponentiation assignment[...]
Array literal{...}
Object literal"..."
String literals$
String format character~
Used to name anonymous function<-
Return operator\
New line character?
Unknown Value
int x = 10
This will declare the variable and give it a value of 0
int x
Constants are in all caps
int X = 10
This will declare the variable and give it a value of 0
int X
The following constants are built into the system:
_
: Represents an empty value or nothingness.T
/F
: Boolean values representing true/false conditions.?
: Used when you don't know the return type of a function etc.
_ = funtionWithUnknownReturnType()
int x = 2
real y = 2.1
int x = 2 + 4 / 2 * 9 - 5 % 3^2
x += 3
x -= 4
x *= 5
x /= 6
x %= 7
x ^= 2
bool x = T
bool y = F
str x = "Hello, world"
str y = "123 - 2"
str z = "Testing 123"
str x = "hello world"
int result = x.length()
Result:
11
str result = "Hello $ world $".format("there", 500)
Result:
"Hello there world 500"
str x = "hello"
str y = " world"
str result = x + y
result += " !"
Result:
"hello world !"
array a = [1, 2, 3]
array b = ["hello", 12, ["world", 9.2]]
array a = [1, 4, "hello"]
int result = a.length()
Result:
3
array a = [1, 2, "hello"]
a.append(9.12)
# OR
a = a.append(9.12)
# OR
a += 9.12
Result:
[1, 2, "hello", 9.12]
array arr = [1, 2, "hello"]
str result = arr.join(", ")
Result:
"1, 2, hello"
array arr = [1, 5, 90]
int result = arr[2]
Result:
90
See Functions
obj object = {
name: "John Doe",
age: 30,
city: "New York",
property: value,
method: fn name() {<- "Hello"}
}
int result = object.age
Result:
30
object.newProperty = "I am a new property"
Result:
{
name: "John Doe",
age: 30,
city: "New York",
property: value,
method: fn name() {},
newProperty: "I am a new property"
}
IDK result = object.method()
Result:
Hello
object.newMethod = fn name(){<- "New method"}
Result:
{
name: "John Doe",
age: 30,
city: "New York",
property: value,
method: fn name(){<-},
newMethod: fn name(){<- "New method"}
}
array result = object.keys()
Result:
[
"name",
"age",
"city",
"property",
"method",
"newMethod"
]
array result = object.values()
Result:
[
"John Doe",
30,
"New York",
value,
fn name(){},
fn name(){<- "New method"}
]
boolean result = object.hasAttr("age")
Result:
T
object.update({"gender" : "male"})
The update
function adds one or more attributes to the object. If an attribute already exists it will be overwritten. The return value is null.
unknown x = 3
unknown y = "Hello"
unknown z = {a : 7, b : 4}
Result:
3
"Hello"
{a : 7, b : 4}
Return a integer version of the input.
int i1 = Int("34")
int i2 = Int(43.2)
Output:
i1 = 34
i2 = 43
Return a real version of the input.
real r1 = Real("34.56")
real r2 = Real(34)
Output:
r1 = 34.56
r2 = 34.0
Return a string version of the input.=
str s1 = Str(23)
str s2 = Str(64.2)
Output:
s1 = "23"
s2 = "64.2"
Prints the output of any type to console. Example usage:
output("hello world")
Output:
hello world
Prints the prompt and then reads the input from user and returns it as string. Example usage:
str input = input("> ")
Input (user):
1234567890
Output:
1234567890
Returns current date and time as a real value. Example usage:
int today = now()
Output:
375612369804852324361987698
Pauses execution for specified amount of seconds. Example usage:
wait(1) # waits for one second
Generate hash code for data(sha256)
str hsh = hash("Hello World!")
Evaluates the passed in code.
unknown result = eval("'Hello world'")
Functions are defined using the fn
keyword followed by its name and parameters in parentheses. The function body is enclosed within curly braces.
fn add(x, y) {<- x + y}
int result = add(2, 5)
Result:
7
Delete statement removes variable from memory. It's important to use it when you don't need a value anymore to free up some memory.
int a = 3
del a
After this statement, variable 'a' will be deleted from the memory. Trying to access it after deleting will cause an error.
(T)
(T | F)
("hello" != "world")
(5 >= 2)
(5 != 2)
(5 > 2)
(T & F)
(F)
(5 == 2)
(5 < 2)
(5 <= 2)
("hello" == "world")
if (T) {
<- "True"
} else {
<- "False"
}
Result:
True
if (F) {
<- "First False"
} else {
if (T) {
<- "Second True"
} else {
<- "Both False"
}
}
Result:
Second True
Case statements are similar to if else statements, but they can handle multiple conditions. They work by comparing a value with different cases and executing the code block of the value if it matches. The code block is a default code block and does not need to return a value. You can use any datatype.
int x = 3
str r = match x {
case 1 {<- "one"}
case 2 {<- "two"}
case 3 {<- "three"}
case 4 {<- "four"}
case 5 {<- "five"}
}
output(r)
Result:
three
Conditions are the same as if statements
int a = 0
while (a < 2) {
output(a)
a += 1
}
Result:
0
1
int b = 0
while (T) {
output(b)
b += 1
}
This will run forever, as the while loop's condition always evaluates to true (T
).
To exit early from a loop you can use break
.
int c = 0
while (T) {
output(c)
c += 1
if (c == 5) {
break
}
}
Result:
0
1
2
3
4
continue
skips the rest of the current iteration and jumps directly to the next one.
d = 0
while (T) {
d += 1
if (d % 2 == 0) {
continue
}
output("I am odd!")
}
Result:
I am odd!
I am odd!
I am odd!
...
For loops have three parts separated by colons (,
)
for (int i = 0, i < 5, i += 1) {
output(i)
}
Result:
0
1
2
3
4
The variable i
starts at 0 and continues until it is no longer less than 5. After each iteration, i
is incremented.
for (int j = 0; j < 10; j += 1) {
if (j == 5) {
break
}
}
Result:
0
1
2
3
4
The continue
statement skips the rest of the code in the current iteration and moves on to the next one.
for (k = 0; k <= 9; k += 1) {
if (k % 2 == 0) {
continue
}
}
Result:
1
3
5
7
9
For-each loops are used when you want to perform an action on each element in a collection without having to manually iterate through it using an index.
array a = [6, 4, 29, 234, 1209, 98203, 12, 0, 2]
for each (int i in a) {
output(i)
}
Result:
6
4
29
234
1209
98203
12
0
2
The do-while loop works similarly to the while loop, but it runs at least once before checking the condition.
int c = 0
do {
output(c)
c += 1
} while (c < 3)
Result:
0
1
2
Do-while loops can be useful when you want to ensure that your code block executes at least once regardless of whether or not the condition is false.
int j = 0
do {
j += 1
if (j > 5) {
break
}
} while (T)
Result:
1
2
3
4
5
int k = 0
do {
k += 1
if (k % 2 == 0) {
continue
}
output(k)
} while (k < 10)
Result:
1
3
5
7
9
import math as m, debug as d
import math, debug
Phi will first check if there is a module with the name then it will check if there is a file in the directory where the current file is located.
output(math.root(16, 2))
output(m.root(16, 2))
Result:
4
4
output(math.pi)
Result:
3.141592653589793
Also the format for the modules
export obj name = {
variable : value,
function : value
}
Example:
export obj math = {
pi : 3.141592653589793,
root : fn r(radicand, index) {<- radicand^(1 / index)}
}
The try block is where you put the code that might throw an error. The catch block is where you handle it if there is one.
try {
int x = 5 / 0
} catch (zeroDivisionError) {
output("Can't devide a number by 0")
}
Result:
Can't divide a number by 0
You can also throw an error if something goes wrong in your code. This is useful when you want to handle errors yourself instead of letting them crash your program.
throw syntaxError "message"
This will throw an error with the message "message"
array contents = readFile("test.txt")
Reads all lines from test.txt
and stores them in the array contents
# text.phi
export array text = [
"Hello, World!",
"This is read text"
]
# main.phi
import text
output(text)
Output:
["Hello, World!", "This is read text"]