Coder Social home page Coder Social logo

ilo's Introduction

ilo

A simple interpreted scripting language.

Coverage badge

Current state

  • Comments
  • Simple expressions (math, simple strings (no interpolation))
  • Expression statements
  • Global variables
  • Empty variables
  • Block statements
  • if / else
  • and and or
  • while loops
  • Native functions:
    • out to output content
    • ask to get user input:
    name = ask("What’s your name?") // name = user answer
    • time to get the time since the Epoch, in nanoseconds
    • size to get the size of a string
    • cmd to run a shell command and get the output:
    file = cmd("cat file.txt") // file = <content of file.txt>
    • size to get the size of a list
    • lines to get an array of the lines of a string (useful to iterate on lines)
  • User-defined, named functions
  • Everything else

Installation

  1. Clone the project
git clone [email protected]:symsmith/ilo.git
  1. cd into the project
cd ilo
  1. Check the usage of the CLI
cargo run -- -h # use -- to pass arguments

Syntax

Comments
// single-line comment
/* multiline
comment */
Variables
// declaration
a = 2
// assignment
a = 3
// fixed type
a = "string" // type error
// usage
out(a * 2)

Variables are scoped to statements: basically, if you define a variable inside braces you can’t use it outside of them.

Since the syntax for declaration and reassigment is the same, the outer scopes are searched in "inside to outside" order when assigning a value. If no variable with this name is found, it is created in this scope.

if true {
  b = 4 // declaration
  a = 3 // assignment of outer scope is fine
}
out(b) // runtime error: b not found

The rule is: you can use any variable in your scope or those above, and the variable you create can be used in your scope and those below yours.

Empty

// `empty` means "no value"
a = empty(number) // empty primary value needs to be typed (boolean or number)
a = 3             // type gets set
a = "a"           // type error
a = empty         // type is still number, no explicit type needed
a = "a"           // type error

// an empty string is defined only with ""
b = ""
c = empty(string) // syntax error: empty string variables cannot be initialized this way

Numbers

// numbers are 64-bit floats (doubles)
a = 2
a = 2.0 * 3
a = 3 % 2  // 1 (remainder of euclidean division)
a = -3 % 2 // 1
a = 2^3    // 8 (exponentiation)
a /= 4     // 2; or +=, -=, *=, %=, ^=
a++        // 3; or a--

Booleans

Only the literal true is evaluated to true. Everything else is "falsy". The and and or operators always return booleans.

a = 2
a == 2                // true
a != 2                // false
1 == 2 or 1 == 1      // true
1 == 1 and 2 == 2     // true
"a" or 2              // false
!(1 == 2) == (1 != 2) // true
1 == true             // false
"a" != 4              // true
/*
or: evaluates left-hand-side and skips evaluation
    of right-hand side if it is true
and: evaluates left-hand-side and skips evaluation
    of right-hand side if it is false
*/

Strings

m = "strings can be
multiline"
"a" + "b" // "ab"
"a" + 3   // type error
"a" * 3   // "aaa"
"a" * 0   // ""
"a" * -1  // runtime error

a = "world"
b = "hello {a + "!"}" // "hello world!"
b = "hello {{a + !}}" // "hello {a + !}" ({{ escapes {)

b = r"hello {a}" // "hello {a}" (raw string)

out("hello" + " world") // "hello world"
size("hello")           // 5

a[0]           // "w"
a[-2]          // "l"
a[1] = "d"     // a == "wdrld"
a[2] = "hello" // runtime error
a[3] = 3       // type error

Lists

// creation
// explicit type for empty list to enforce single type
a = number[]    // or a = string[], a = boolean[],
                // a = string[][]...
b = []          // type error, explicit type needed
b = ["a", 1]    // type error
a = [3]
s = ["a"] * 3   // ["a", "a", "a"], all different references
t = [1, 2] * 3  // [1, 2, 1, 2, 1, 2]
t = a * 3       // [3, 3, 3]
t = [1...3]     // [1, 2, 3]
t = [1...1]     // [1]
t = [1...-1]    // [1, 0, -1]
t = [1.2...3.4] // type error, int needed both sides

// read, write
s[1]        // "a"
s[1] = "b"  // s == ["a", "b", "a"]
s[2] = 3    // type error
s[-1] = "b" // s == ["a", "b", "b"]

// append
a = [3]
b = a + 2             // [3, 2]
b = 2 + a             // [2, 3]
b = [1, 2] + "a"      // type error
b = [1, 2] + [3, 4]   // [1, 2, 3, 4]
b = [[1, 2]] + [3, 4] // [[1, 2], [3, 4]]

// filter
b = [2, 1, 2] - 2      // [1] (remove occurences)
b = [2, 1, 3] - [2, 3] // [1] (remove occurences)
b = [1, 2] - "a"       // [1, 2] (no occurence)

// pop
b = [1, 2] / 1          // [1] ("slash"/cut n last)
b = [1, 2] / "a"        // type error
b = 1 / [1, 2]          // [2] ("slash"/cut n first)
b = 1 / [1, 2] / 1      // [] = (1 / [1, 2]) / 1
b = [1, 2] / 1 / [1, 2] // = ([1, 2] / 1) / [1, 2] 
                        // = [1] / [1, 2]
                        // type error

// belonging
a = [1...4]
2 in a   // true
"a" in a // false
-1 in a  // false

// list length
size([1...3]) // 3
size(4)       // type error

Objects

o = {
  key: "value",
  "Some other key": 3,
  a: [3, 5],
  b: { key: "other value" },
  c: f () {
    return "hello"
  }, // optional `,` at end
}

// read, write
o.key     // "value"
o["key"]  // "value"
o.c()     // "hello"
o.key = "something else"
o.key = 4 // error

// create key
o.new = "hello"
o.new // "hello"

// delete key
delete(o.new)
o.new // runtime error

// keys list
keys(o) // ["key", "Some other key", ...]
Blocks
a = 3
{
  a = 4
  b = 2
  out(a) // 4
  out(b) // 2
}
out(a) // 4
out(b) // runtime error
Loops
a = 0
while a < 10 {
  out("something")
  a++
  break    // stops closest loop
  continue // goes to next iteration of closest loop
}

// for is for lists and strings only
b = [1...10]
for item in b {
  out(b) // 1 2 3...
}

c = "word"
for char in c {
  out(char) // w o r d
}

for char, i in c {
  out(char + " {i}") // w 0 o 1 r 2 d 3
}
Conditionals
a = 3
if a < 10 {
  out("something")
} else if a > 10 {
  out("something else")
} else {
  out("a = 10")
}

t = a == 10 ? "a = 10" : "a != 10"
u = a ? 1 : 2         // type error (a not boolean)
u = a == 10 ? "1" : 2 // type error (type mismatch)

match a {
  1 -> out("1")
  2 or 3 -> {
    out("something")
  }
  default -> out("else") // optional
}
Functions
f someFunc(a, b) {
  c = a + b
  return c
}

f inlineFunc(a, b) -> a + b

// anonymous functions
a = f () -> out("something")
a() // "something"

f () {
  doSomething()
  return "something"
}() // "something"

f func2() {
  return // syntax error
}

f func3(a) {
  if (a == 3) {
    return "a"
  } else {
    return 1 // type error (branches mismatch)
  }
}

Native functions

a = ask("test")       // string
out(a)                // output some content
size([1, 2])          // get the size of a list
size("hello")         // get the length of a string
b = cmd("echo hello") // shell command: b == "hello"
time()                // time since 1/1/1970, midnight, in nanoseconds
lines("hello\nworld") // ["hello", "world"]
delete(o.key)         // delete a key from an object
keys(o)               // get a list of the keys of an object

Credits

The development of ilo was very much initiated and helped by the book Crafting Interpreters, by Robert Nystrom.

License

MIT

ilo's People

Contributors

symsmith avatar

Watchers

 avatar

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.