Skip to content

leandrogutierrez148/grotsky

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Grotsky

codecov build

Grotsky is a toy programming language. Implemented in go as a Tree-based interpreter. Made after reading the book Crafting Interpreters. You can also find clox and jlox implementations under my github projects.

Grotsky is inspired a little bit by go and python. Uses a C-like style syntax with curly braces but no semicolons, includes some basic collections like lists and dicts. Also has the hability to listen to tcp ports, read environment variables and import modules.

Overview

Get executable from releases.

Run using $ ./grotsky source.gr

Literals

  • strings: "String A"
  • numbers: 10, 10.04, 3.14, -1
  • booleans: true, false
  • lists: ["a", 1, 2]
  • dicts: {"a": 1}

Hello World

io.println("Hello world!")

Comments

# Comments start with '#'

Arithmetic Expressions

io.println(
    1+(2+5*10)/2,
    2^4
)

Outputs

27 16

Comparison & Logical Expressions

io.println(
    true and (false or true),
    1 > 2 and 5 <= 10
)

Outputs:

true false

Lists

let list = [
    "a",
    "b",
    "c",
    "d",
    "e"
]

io.println(list)

Outputs:

["a", "b", "c", "d", "e"]

Dicts

let dict = {
    "a": 1,
    "b": 2,
    "c": 3
}

io.println(dict)

Outputs:

{"c": 3, "a": 1, "b": 2}

Conditionals

let a = 10
if a > 10 {
    io.println("a is bigger than ten")
} elif a > 5 {
    io.println("a is less than or equal to ten and bigger than five")
} else {
    io.println("a is less than or equal to five")
}

Outputs:

a is less than or equal to ten and bigger than five

Loops

While-Loop

let str = ""
while True {
    if str.length == 10 {
        break
    }
    str = str + "a"
}
io.println(str)

Outputs:

aaaaaaaaaa

Classic For-Loop

let list = []
for let i = 0; i < 10; i = i + 1 {
    list = list + [i]
}
io.println(list)

Outputs:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Enhanced For-Loop

Iterate List
let list = [0, 1, 2, 3, 4]
for i in list {
    io.println(i)
}

Outputs:

0
1
2
3
4
Iterate Dict
let dict = {
    "a": 1,
    "b": 2,
    "c": 3
}
for k, v in dict {
    io.println(k, v)
}

Outputs:

b 2
c 3
a 1
Unpacked List of Lists
let listOfLists = [
    ["a", 1, 3],
    ["b", 2, 4],
    ["c", 3, 5]
]
for x, y, z in listOfLists {
    io.println(x, y, z)
}

Outputs:

a 1 3
b 2 4
c 3 5

Functions and Closures

fn makeCounter() {
    let n = -1
    fn wrap() {
        n = n + 1
        return n
    }
    return wrap
}

let counter = makeCounter()

io.println(counter())
io.println(counter())
io.println(counter())

Outputs:

1
2
3

Classes

Simple Class

class A {
    init(n) {
        this.n = n
    }

    print() {
        io.println("N:", this.n)
    }
}

let a = A(10)
a.print()

Outputs:

N: 10

Superclasses

class A {
    print() {
        io.println("Printing:", this.text)
    }

    appendToText(text) {
        this.text = this.text + text
    }
}

class B < A { # Inherits from A
    init() {
        this.text = ""
    }

    appendToText(text) {
        if this.text.length + text.length < 5 {
            super.appendToText(text) # Call to method on superclass
        }
    }
}

let b = B()
b.appendToText("Hello!") # str.length > 5
b.print()
b.appendToText("Hell")
b.print()

Outputs:

Printing: 
Printing: Hell

Magic Methods

Available magic methods: add, sub, div, mod, mul, pow, neg, eq, neq, lt, lte, gt, gte.

class Magic {
    init(value) {
        this.value = value
    }

    add(other) {
        # Addition as in result = this + other
        this.value = this.value + other.value
    }

    print() {
        io.println("Magic is:", this.value)
    }
}

let a = Magic(1)
a + Magic(2)
a.print()

Outputs:

Magic is: 3

Modules

File utils.gr:

fn map(list, mapFn) {
    let out = []
    for e in list {
        out = out + [mapFn(e)]
    }
    return out
}

Usage:

let utils = import("utils.gr")
let list = [0, 1, 2, 3, 4]
io.println(utils.map(list, fn (e) 2 ^ e))

Outputs:

[1, 2, 4, 8, 16]

Net utils

TCP Socket

let socket = net.listenTcp("127.0.0.1", "6500")
while true {
    let conn = socket.accept()
    io.println("Received connection from:", conn.address())
    conn.write("ok\n")
    conn.close()
}

Try from console:

$ telnet localhost 6500
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
ok
Connection closed by foreign host.

Outputs:

Received connection from: 127.0.0.1:52238

Env Variables

let lang = env.Get("LANG")
io.println(lang)

Outputs:

en_US.UTF-8

Try-Catch

try {
    let utils = import("utils.gr")
} catch err {
    io.println(err)
}

Outputs:

open utils.gr: no such file or directory

About

Grotsky Programming Language

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Go 99.9%
  • Shell 0.1%