Skip to content

ChaseYalon/toy_comp

Repository files navigation

Welcome to ToyLang

A demonstration of the CTLA garbage collection model. Please reach out to chaseyalon@gmail.com or chase@chaseyalon.com with questions/comments. This repository is actively maintained, issues and PR's are appreciated.

DOCS

ToyLang is a compiled language, meaning that it produces binary executable files. The currently supported platforms are x86_64-Windows and x86_64-Linux, both use the GNU abi. By default if you run the binary it expects a path to a .toy file that it will compile. You can also use --repl to bring up a repl. The language is based on LLVM and uses "-O3" optimizations by default, but the --repl or --no-opt flags will cause it to use no optimizations. Also right now only ASCII encoding for .toy files is supported. UTF-8 will be supported in the future.

Datatypes

Toy lang supports the following first class datatypes - meaning they are fully supported for all situations
  • int: 64 bit signed integer
  • float: 64 bit signed float
  • bool: 64 bit integer representing a bool (value of 1 for true, 0 for false)
  • str: Represents a string of characters, you can call len(str) to get the length, but strings are immutable under the hood, so be aware of that
  • Struct Structs are custom heap allocated data structures created by the user. If you create a struct Point, you can also do Point[], the same way you can with any other type
  • I touched on it above but all first class types can have n dimensional arrays declared like int[][] for an integer matrix. Lengths are not necessary and the arrays behave like vectors in the strict sense, as they are contiguously allocated in (heap) memory, but can grow, and will be able to shrink in the future
The following are second class datatypes, which may be used in certain scenarios however should be avoided by default, and are not guaranteed to work in all scenarios,
  • Void: represents a function that does not return, stability and compilation are guaranteed when using it as a return type from a function, and for no other place
  • Any: Will disable the typechecker when used, so it assumes you have manually checked your types, if they are wrong you will get a nasty error, while the following is allowed: functions may return any, and take any as parameters, variables may assigned to any, and you may make any[]'s it is highly unstable for all other use cases and should be avoided if at all possible
  • Functions: This language has 0, nada, nil functional features. Maybe they will be added later but for now treat all functions like C functions. Also DO NOT USE COLONS IN YOUR FUNCTION NAMES!!! THey will confuse the name mangler

Syntax

To declare a variable, use:

let x = 9;

The type is automatically inferred. If you want to explicitly specify a type:

let x: str = "hello world";

Notice the semicolons!!!

Variable reassignment and compound operators are also supported

let x: float = 9.2;
x += 315.2;

You can use an if statement as follows

let x = true && !false;

if x {
    println("it worked");
} else {
    println("it failed");
}

Else is supported, but else-if chains are not.

You already saw a function call above but here is the general syntax for functions

fn add(a: int, b: int): int {
    return a + b;
}

let x = add(9, 3);

All function parameters and return types (including void) must be stated explicitly, here is a void example

fn my_println(s: str): void {
    println(s);
}
my_println("hi mom!!!");

You can see a list of builtin functions at the bottom

Currently only while loops are supported, but iteration loops (for) will be in the (very) distant future

let i = 0;
while i < 7 {
    if i == 3{
        continue;
    }
    if i == 6 {
        break;
    }
    println(i);
}

will print 1, 2, 4, 5,

Arrays are also fully supported

let arr = [0, 1, 2, 3, 4];
arr = [9, 2];
let x = arr[0];
println(arr);

prints [9, 2]

Structs are also fully supported

struct Point{
    x: float,
    y: float
}
let origin = Point{x: 0.0, y: 0.0};
fn print_point(p: Point): void{
    print("Point{x: ");
    print(p.x);
    print(", y: ");
    print(p.y);
    print("};");
}

You can bind methods to structs like this, lets redo that print_point

struct Point{
    x: float,
    y: float
}
for Point {
    fn print_point(){// note the inferred return type of void
        print("Point{x: ");
        print(this.x);//notice this keyword
        print(", y: ");
        print(this.y);
        print("};");
    }
}
let origin = Point{x: 0.0, y: 0.0};
origin.print_point(); //outputs Point{x: 0.0000, y: 0.0000};

Builtin functions

  • print(s: any): void prints an output to the standard output
  • println(s: any): void prints an output to the standard output with a newline
  • len(v: any): int the signature takes an any but can only be called on a string or an array, will return the number of characters or elements respectively
  • int(i: any): int returns the integer value of a value an object if it is a string of "17" it will become 17 otherwise it will panic, and for floats it will round
  • str(s: any): str returns the string value of any convertible object, for booleans false => "false", true is the same, for an integer 7 => "7", and same with floats
  • float(f: any): float returns a float from a convertible value, will turn "5.3" => 5.3, false => 0.0, true => 1.0, will turn 1 => 1.0
  • bool(b: any): bool will turn "true" => true, same with false and will panic for any other string, will turn 1 => true, 0 => false and wil panic otherwise, and will round a float and use do the same

STDLIB Functions

std.fs

  • read_file(path: str): str reads all bytes from a file as a UTF-8 string
  • write_file(path: str, content: str)overwrites all concent in the file with the specified value
  • append_file(path: str, content: str)appends content to the back of a file

std.time

  • ms_since_unix_epoch(): int returns the number of milliseconds since 12:00 AM, Jan 1, 1970
  • now(): int alias for ms_since_unix_epoch()
  • current_year(): int returns the current year
  • current_month(): int returns 1 for january and 12 for december
  • current_month_name(): str returns the name of the current month
  • current_day(): int returns the current day of the month
  • current_date(): Date returns a struct containing year, month, day as ints, and has a .to_str method
  • sleep(ms: int) will pause all program execution for the specified amount of tme

std.sys

  • exit(code: int) exits the current process with the provided exit code
  • abort() immediately terminates the current process with exit code -1
  • panic(message: str) prints the message and then aborts the process
  • get_pid(): int returns the current process ID
  • argv(): str[] returns the process argument vector as an array of strings
  • argc(): int returns the number of command line args
  • os_name(): str returns the operating system name
  • core_count(): int returns the number of available CPU cores
  • version(): str returns the toy lang version string (currently 0.0.2)
  • version_info(): str returns the extended release tag (currently ALPHA_0.02_GRAY)
  • is_little_endian(): bool returns true when running on a little-endian system
  • is_big_endian(): bool returns true when running on a big-endian system

std.net

A brief note, if you are worried about security, this uses libcurl and will imbed a trusted public key as binary into your program. That is what the compiler does, security beyond that is your responsibility. If you are doing anything sensitive PLEASE use the ffi and do it in C. This language is not tested enough yet.

  • get_url(url: str): str will curl the specified url and return a string of the results
  • configure_http_server(port: int, timeout: int) will configure the global server, MUST BE CALLED BEFORE CONNECTION REQUESTED. Timeout is in ms.
  • connection_requested(): bool will return true when a connection is requested, false otherwise
  • HttpRequest{method: str, path: str, client_ip: str, body: str} Is used to represent an incoming http request
  • read_request(): HttpRequest Once a connection has been requested you can use read_request to read it, and can treat it like any other struct
  • close_client() Will close the client connection, but not the server.
  • write_response(code: int, content_type: int, body: str) Will write a response back to the open client. Code is the http status code (200 = good, 500/503 = server error, 404 = page not found). Content_type is 1 = text/plain, 2 = text/html 3 = application/json 4 = application/javascript. Body is the text of the response
    • Build Instructions

      If you do not have the build system setup (mys2 - clang/llvm), rust on the correct toolchain, cmake, and ninja run the following.
      
      python setup_build_system.py #will install build system
      
      then you can do
      
      cargo run -- --repl # will get you a repl
      cargo run -- PATH_TO_FILE # will compile a .toy file
      

About

To compiler

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages