Skip to content
/ thusly Public

The Thusly programming language - Coming to life through a one-pass compiler and a stack-based virtual machine.

License

Notifications You must be signed in to change notification settings

elle-j/thusly

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

85 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The Thusly Programming Language

A general-purpose programming language coming to life through a custom one-pass compiler and a stack-based virtual machine.

👉️ The language is currently being developed, but the implemented features can be seen in Milestones. This README is also in development.

Table of Contents

Playground

Try out Thusly in the WASM-based interactive playground directly in the browser.

Thusly Playground

Language

Characteristics

  • General-purpose
  • Interpreted
  • Dynamically typed
  • Imperative
  • Garbage collected

Syntax

The development of both the language and the surrounding documentation is currently on-going, but the following is a subset of the language:

Variables, Data Types, and Literals

Variable declarations in the Thusly programming language.

Selection

An if-statement in the Thusly programming language.
An if-statement in the Thusly programming language.

Loop

A foreach-loop in the Thusly programming language.
A foreach-loop in the Thusly programming language.
A while-loop in the Thusly programming language.

Whitespace:

Whitespace is semantically insignificant except for newline characters on non-blank lines.

Design

To read more about the architectural design, implementation details, and follow along walk-throughs of examples of tokenization, parsing, compilation, evaluation, and execution, see design/implementation.

Milestones

Milestone 1: Support arithmetic, comparison, and equality operations

  • The terminals in the initial grammar can be identified from user input via a multi-line file or single-line REPL input and then tokenized.
  • Arithmetic expressions using number (double) can be evaluated.
    • Addition (+)
    • Subtraction (-)
    • Multiplication (*)
    • Division (/)
    • Modulo (mod)
    • Unary negation (-)
    • Precedence altering (())
  • Comparison expressions using number can be evaluated.
    • Greater than (>)
    • Greater than or equal to (>=)
    • Less than (<)
    • Less than or equal to (<=)
  • Equality and logical negation expressions using number, boolean, text (string), and none can be evaluated.
    • Equal to (=)
    • Not equal to (!=)
    • Logical not (not)
  • Concatenation of text literals using + can be evaluated.

Milestone 2: Support variables and control flow

  • Temporary @out statement can be executed.
  • Global and local variables can be defined and used.
    • Declaration and initialization (var <name> : <expression>)
    • Assignment expression (<name> : <expression>)
  • Variables adhere to lexical scope.
    • Standalone block
      block
        <statements>
      end
      
  • Logical operators can be evaluated.
    • Conjunction (and)
    • Disjunction (or)
  • Control flow statements can be executed.
    • Selection

      • if
      • elseif
      • else
      if <condition>
        <statements>
      elseif <condition>
        <statements>
      else
        <statements>
      end
      
    • Loops

      • Bounded (foreach)
      foreach <name> in <start>..<end> step <change>
        <statements>
      end
      
      Example 1
      // `<change>` expression is implicitly 1
      foreach value in 0..10
        @out value
      end
      
      Example 2
      var a: 0
      var b: 10
      var c: 2
      foreach value in a..b step c
        @out value
      end
      
      • Unbounded (while)
      while <condition> { <change> }
        <statements>
      end
      
      Example
      // `{ <change> }` expression is optional
      var i: 0
      while i < 10 {i +: 1}
        @out i
      end
      
  • Augmented assignment expressions can be evaluated.
    • Addition and assignment (+:)
    • Subtraction and assignment (-:)
    • Multiplication and assignment (*:)
    • Division and assignment (/:)
    • Modulo and assignment (mod:)
  • Range comparison expression can be evaluated (<value> in <min>..<max>)
  • TODO (more milestones will be added here)

Milestone 3: Provide an interactive playground

  • A Thusly VM can run and execute code in the browser via an interactive playground.

Milestone 4: Support first-class functions

  • Functions can be defined and invoked.
  • Closures are supported.
  • Functions are first-class citizens.
  • TODO (more milestones will be added here)

Example Input

This section is for briefly demonstrating implemented functionality thus far and expected behavior when running your code.

By inputting code from either a file or via the REPL, the VM will interpret it and output the result if an @out statement is used.

Table 1: Valid user input (expressions)

Example input Expected output Expected precedence parsing
1 + 2 * 3 / 4 2.5 1 + ((2 * 3) / 4)
(1 + 2) * 3 / 4 2.25 ((1 + 2) * 3) / 4
1 + -2 - -3 2 (1 + (-2)) - (-3)
1 > 2 = 3 > 4 true (1 > 2) = (3 > 4)
false != not(1 + 2 >= 3) false false != (not((1 + 2) >= 3))
"he" + "llo" = "hello" true ("he" + "llo") = "hello"
"keep " + "on " + "coding" keep on coding ("keep " + "on ") + "coding"
false and false or true true (false and false) or true
true or true and false true true or (true and false)

Table 2: Valid user input (statements)

Example input Expected output
var first: "Jane"
var last: "Doe"
var full: first + " " + last
@out full
Jane Doe
var x: 1
var y: 2
var z: x: y
@out x
@out z
2
2
var x: "global"
@out x

block
x: "changed global"
var x: "local"
@out x
end

@out x
global
local
changed global
var x: 0
if x < 5
@out "in if"
else
@out "in else"
end
in if
foreach value in 0..2
@out value
end
0
1
2
var a: 0
var b: 2
var c: 0.5
foreach value in a..b step c
@out value
end
0
0.5
1
1.5
2
var x: 0
while x < 4 {x +: 1}
@out x
end
0
1
2
3

Table 3: Invalid user input

Example input Error type Expected error reason
"one" + 2 Runtime + operates on number only or text only
"one" < 2 Runtime < operates on number only
!true Comptime ! is only allowed in != (use not)
x: 1 Comptime x has not been declared
var x: 1
1 + x: 2
Comptime 1 + x is an invalid assignment target
(+ has higher precedence than :)

Getting Started

Prerequisites

  • A C compiler (e.g. Clang or GCC)
  • CMake version 3.20 or later

Building the Project

Run the below command to make Thusly come to life. It will create a top-level bin directory where the configured and compiled project will be located along with the executable binary cthusly.

./build.sh

If permission is denied, first add executable permission to the build script by running: chmod +x build.sh.

Running Code

Once you have built the project you can go ahead and feed it some code to interpret thusly (..get it?):

Usage example:

$ ./bin/cthusly --help

Usage: ./bin/cthusly [options] [path]

    The REPL (interactive prompt) starts if no [path] is provided

    -h,     --help           Show usage
    -d,     --debug          Enable all debug flags below
    -dcomp, --debug-comp     Show compiler output (bytecode)
    -dexec, --debug-exec     Show VM execution trace

Flags:

Currently, only 1 flag may be provided.

Interpret code from a file:

./bin/cthusly path/to/your/file

Start the REPL (interactive prompt):

./bin/cthusly

Exit REPL:

Press Cmd + D (Mac) or Ctrl + D (Windows).

Example:

$ ./bin/cthusly

> @out "he" + "llo" = "hello"
true
> @out (1 + 2) * 3 / 4
2.25
> 

Enable/disable debug:

For the debug flags to have an effect, the following macro in src/common.h need to be defined.

  • DEBUG_MODE

You may comment or uncomment it to disable or enable support for the flags (then rebuild the project).

License

This software is licensed under the terms of the MIT license.

About

The Thusly programming language - Coming to life through a one-pass compiler and a stack-based virtual machine.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published