Code Monkey home page Code Monkey logo

shum's Introduction

shum

It's called шум because it is noisy. I guess.

This is my attempt at creating a simple stack-oriented language. It's implemented in Java and translates the written Shum code to JVM bytecode. There are a couple of built-in functions and operators supported at the moment.

Running

Run the build.sh script. It creates the docker image and runs it. You end up in the bash after a successful execution.

You can try running example shum files as follows:

bash>shum ./examples/hello_world.shum
bash>shum ./examples/fibonacci.shum

Obviously, you can create your own files and run them in the same way.

Documentation

Shum is a stack-oriented language, meaning conceptually there exists a stack and we simply push and pop elements onto that stack. For example, to add two numbers a and b, we should push a first, then b, and finally execute add operation, The result will be pushed onto the stack as well. Shum uses the Reverse Polish Notation. Shum is implemented in Java 17 and it produces JVM bytecode.

Simple operations

Specifying a constant value simply pushes that value onto the stack.

        // stack: [] <- top of the stack
1       // stack: [1]
2       // stack: [1 2]
"Hello" // stack: [1 2 "Hello"]
len     // stack: [1 2 5] => because len("Hello") = 5 and it got pushed onto the stack
+       // stack: [1 7] => 2 + 5 = 7
-       // stack: [-6] => 1 - 7

Adding two numbers and printing the result:

1 2 + print
// the execution happens as follows:
// [1] <- top of the stack
// [1 2]
// [1 2] +
// [] (1 + 2)
// [3] print
// [] => "3"

There are quite a bit of built-in functions.

function signature what it does
+ int int -> int adds two numbers
- int int -> int subtracts two numbers
* int int -> int multiplies two numbers
/ int int -> int performs integer division
% int int -> int performs mod operation
pow int int -> int raises number to power
> int int -> bool greater than
>= int int -> bool greater equal
< int int -> bool less than
<= int int -> bool less equal
== int int -> bool equal
!= int int -> bool not equal
not bool -> bool negation
abs int -> int returns absolute value
neg int -> int negates an integer
incr int -> int increments integer
decr int -> int decrements integer
print T -> () prints the value at the top of the stack
dup ... duplicates the element at the top of the stack
swap ... swaps two elements at the top of the stack
drop ... drops the element at the top of the stack
upper string -> string to uppercase
lower string -> string to lowercase
trim string -> string trims
startsWith string string -> bool if string starts with another string
endsWith string string -> bool if string ends with another string
isEmpty string -> bool is string empty?
isBlank string -> bool is string blank?
len string -> int length of the string
contains string string -> bool if string contains another string
substr string int int -> string substring of a string in range
++ string string -> string concatenate two strings
isUpper string -> bool is the string uppercase?
isLower string -> bool is the string lowercase?

Control-flow: if statements

Syntax:

[bool-producing-instructions] if [true branch] (else [false branch])? end 
1 10 <= if
    1 print
else
    2 print
end

// or with no else

1 10 <= if
    1 print
end

We currently do not support else if statements, but we can align if and elses in a way that it will resemble else if:

1 loop dup 20 <= do
    dup 15 % 0 == if
        "FizzBuzz"
    else dup 5 % 0 == if
        "Buzz"
    else dup 3 % 0 == if
        "Fizz"
    else
        dup
    end end end
    print
    1 +
end

Control-flow: loops

Syntax:

[...some instructions] loop [bool-producing-instructions-for-condition] do [loop-body] end
1 loop dup 20 <= do
    dup print
    1 +
end

Variables

Syntax to declare a variable:

let [varName]:[dataType]

When a variable is declared, the initial value is null. There are two operations we can do with a variable:

  • varName@ - loads the value of the variable onto the stack
  • varName! - binds the value at the top of the stack to the variable with the given name

The syntax for variable operations is taken from Forth.

For example, to sum numbers from 1 till 15, we can do:

let sum:int                 // define a variable called `sum` which is an integer
0 sum!                      // initialize the variable to 0
1 loop dup 15 <= do         // loop till 15
     dup sum@ + sum!        // sum the loop increment with the sum value, and save it back to sum
     1 +                    // increment to advance the loop pointer
end
sum@ print                  // print the result which should be 120

Variables defined outside of any function are global, and the ones declared inside of a function/loop/if statement are local. Global and local variables can have the same name, and in that case, the local variable will shadow the global one for that function.

A little bit of an exaggerated example of a function using local variables.

func sumTill int -> int =
    let till:int
    till!            // take the value of the first parameter since it is pushed onto the stack

    let counter:int
    0 counter!

    let sum:int
    0 sum!

    loop counter@ till@ <= do
        counter@ sum@ + sum!
        counter@ 1 + counter!
    end

    sum@
    return
end

Custom functions

We can use the func keyword to create functions. Function declarations must end with end keyword.

func hello = ... end

If function expects a parameter, we need to mention the types, and also what it returns (if there's any):

func add5 int -> int = 5 + return end

Function parameters can be named as well:

func surroundString word:string left:string right:string -> string =
    ...
end

The return keyword specifies that the function returns a value at the end of its execution. If the function is called somewhere else, and the value produced by the function is needed, then you need to use the return keyword.

Some type signatures:

func foo = ... // takes nothing returns nothing

func foo int -> int = ... // takes an int and returns an int, like abs() function

func foo int = ... // takes an int and returns nothing

func foo -> int = ... // takes nothing an returns an int

func foo int int int -> int = // takes three int and returns an int

Macros

Macros are pretty much like functions, except we only execute their instructions as a part of the caller method without actually invoking another method. Macros do not take parameters.

macro foo = ... end

shum's People

Contributors

rhaeguard avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

Forkers

upl-ecosystem

shum's Issues

Namespaces

So, instead of just each function being present in the prelude, let them have namespaces. Examples:

use str
use list
use set::add

"hello" str/upper
[1 2 3] list/first
() 2 add

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.