Owk

From Esolang
Jump to navigation Jump to search

Owk is a compiled, esoteric, golfing, register-based programming language. created by User:Phase. that runs on the FVM. It is compiled into FVM bytecode, which can be put through the FVM for results.

Owk is parsed line by line. You can make a “fake” line by putting a ;. Comments start with # and are only at the start of a line, whitespace is ignored.

   a=7
   6=84
   #The same as
   a = 7; 6 = 84

There are 16 registers in total, each marked by their hexadecimal counterpart. To load a number to these registers, we use =. (It basically overwrites whatever was in the register before.)

   #Loads 8 to register f
   f=8
   #You can also use capitals
   F=8

To load characters, you use . This will load the ASCII value of the character, though it can’t be over 255. Printing is done with p.

   1='H';2='e';3='l';4='l';5='o';6=' '
   7='W';8='o';9='r';a='l';b='d'
   p1;p2;p3;p4;p5;p6;p7;p8;p9;pa;pb;

You can also do your normal math operations in Owk using the registers.

   #Adds the values of registers a & f and stores it in register e
   e<a+f
   #Multiplies the values of registers 2 & d and stores it in register f
   f<2*d
   #Mods the values of registers 8 & 6 and stores it in register 1
   1 < 8 % 6
   #Transfers the value of register e into register f
   f<e

The available functions are add +, subtract -, multiply *, divide /, mod %, AND &, OR |, XOR ^, left shift <, and right shift >.

Expressions are done by wrapping it around (). It gets parsed by a JavaScript engine, so you can use things like Math.pow(). The answer of the expression can’t be over 255, so be careful!

   f=(2*3+4)
   e=(Math.pow(2,3) + 7)

Since Owk is parsed line by line, you can use the g operator to go to a specific line.

   #Infinite Loop
   f=8;e=6
   f=f*e;g1
   #The number after g is written in hex</source>

Negative numbers can be inputed like normal ones.

   #Negative 2
   f=-2
   #NOT 2
   e=!2
   #Two's complement 2
   d=~2

You can also negate registers.

   #Negative c
   f<-c
   #NOT c
   e<!c
   #Two's complement c
   d<~c

Lambdas

Lambdas are a special part of Owk, and how functions are written. Then are notated in Lambda Calculus, which is different than your normal (x) -> x.

   square:λx.x*x
   add:λx.λy.x+y

Each lambda begins with a name, followed by a : and the function code. Each λ notates a varaible use by the lambda, followed by a . and more variables or the function code. Here’s a side by side example of a Java method and an Owk lambda:

   int add(int x, int y) {
       return x + y;
   }
   add:λx.λy.x+y

And a more complicated one:

   int math(int x, int y) {
       return x * x + y * y;
   }
   math:λx.λy.x*x+y*y;

To use these lambdas, we need to assign the output to a register. It’s inputs will be in parentheses.

   f=math(e,d)

External Resources

The interpreter

Separate implementation:

README.md

# Owk
Owk is a compiled, esoteric, golfing, register-based programming language invented by Phase. This is an attempt of making Owk golfier.

Owk is parsed line by line. You can make a "fake" line by putting a `;`. Comments start with `#` and are only at the start of a line, whitespace is ignored.

```python
a=7
b=84
#The same as
a = 7; b = 84
```

There are 52 registers in total, each marked by a letter in the alphabet, whether capital or not. To load a number to these registers, we use `=`. (It basically overwrites whatever was in the register before.)

```python
#Loads 8 to register f
f=8
#This loads into a different register
F=8
```

To load characters, you use `'`. This will load the ASCII value of the character, though it can't be over **`255`**. Printing is done with `.`.

```python
a='H;b='e
c='l;d='l
e='o;f=' 
g='W;h='o
i='r;j='l
k='d
.a;.b
.c;.d
.e;.f
.g;.h
.i;.j
.k
```

You can also do your normal math operations in Owk using the registers.

```python
#Adds the values of registers a & f and stores it in register e
e=a+f
#Multiplies the number 2 & d and stores it in register f
f=2*d
#Mods the numeric values 8 & 6 and stores it in register a
a=8%6
#Transfers the value of register e into register f
f=e
```

The available functions are add `+`, subtract `-`, multiply `*`, divide `/`, mod `%`, AND `&`, OR `|`, XOR `^`, left shift `<`, and right shift `>`.

Expressions are done by wrapping it around `()`. It gets parsed by a Python engine, so you can use things like `**`. The answer of the expression can be over **`255`**. When outputted though this gets modulo'd by 256.

```python
f=2*3+4
e=2**3 + 7
```

Negative numbers can be inputed like normal ones.

```python
#Negative 2
f=-2
#NOT 2
e=!2
#Two's complement 2
d=~2
```

You can also negate registers.

```python
#Negative c
f=-c
#NOT c
e=!c
#Two's complement c
d=~c
```

## Lambdas
Lambdas are a special part of Owk, and how functions are written. Then are notated in [Lambda Calculus](https://en.m.wikipedia.org/wiki/Lambda_calculus), which is different than your normal `(x) -> x`.

```python
# There are 26 possible parameters stored in
# registers a-z.
square:a*a
add:a+b
```

Each lambda begins with a name, followed by the function code. Here's a side by side example of a Python method and an Owk lambda:

```python
add=lambda a,b:a+b
```
```python
add:a+b
```

And a more complicated one:

```python
math=lambda x,y:x*x+y*y
```

```python
math:a*a+b*b
```

To use these lambdas, we need to assign the output to a register. Its inputs will be in parentheses.

```python
f=math(e,d)
```

There is another separate way to write functions:
```python
@A:A()
```
@ indicates that this is a function, and also this allows recursion to be done.

```A()``` is a function here.

This is not lowercase because the parameters for a function will be in lowercase, and you can't call a function parameter.

## Conditionals
Owk allows a simple form of conditional switching:

```python
a=1-1&1|0
```
This compares 1 and 1 and checks whether they are equal. If so, the value 1 is assigned to a. Otherwise the value 0 is assigned to a.

owk.py

import sys
file=open(sys.argv[1],'r')
text=file.read()

output=""

i=0

while i<len(text):
    if text[i]==';':
        output+='\n'
    elif text[i]==' ':
        pass
    elif text[i]=='#':
        while text[i]!='\n':
            i+=1
    elif text[i]=="'":
        output+="ord('"
        output+=text[i+1]
        output+="')"
        i+=1
    elif text[i]=='.':
        output+='print(chr('
        output+=text[i+1]
        output+='),end="")'
        i+=1
    elif text[i]=='<':
        output+='<<'
    elif text[i]=='>':
        output+='>>'
    elif text[i]=='!':
        output+='int(not '
        i+=1
        try:
            while text[i]!='\n'and text[i]!=';':
                output+=text[i]
                i+=1
        except:
            pass
        output+=')'
        i+=1
    elif text[i]==':':
        output+='=lambda '
        j=i
        try:
            while text[j]!='\n'and text[j]!=';':
                j+=1
        except:
            pass
        a=""
        for x in range(ord('a'),ord('z')+1):
            if chr(x) in text[i:j]:
                a+=chr(x)+','
        a=a[0:-1]
        output+=a+text[i:j]
        i=j-1
    elif text[i]=='@':
        output+='def '
        i+=1
        while text[i]!=':':
            output+=text[i]
            i+=1
        output+='('
        j=i
        try:
            while text[j]!='\n' and text[j]!=';':
                j+=1
        except:
            pass
        a=""
        for x in range(ord('a'),ord('z')+1):
            if chr(x) in text[i+1:j]:
                a+=chr(x)+','
        a=a[0:-1]
        print(a)
        output+=a
        output+='):return '
    else:
        output+=text[i]
    i+=1
print(output)
exec(output)
print(A())