Code Monkey home page Code Monkey logo

cosy-lang's Introduction

Cosy

A work-in-progress systems programming language.

Building

Build the Cosy compiler using cargo build --release. An executable file called cosyc should then appear in the target/release directory. This file can be moved to the root of the repository if preferred.

cosy-lang's People

Contributors

katsaii avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

cosy-lang's Issues

Add `extern` definitions

Specifically, add an extern "intrinsic" declaration so that compiler-intrinsic functions can be exposed to the language, for things such as adding numbers together or allocating memory.

extern "intrinsic" {
  def add_int32(int32, int32) : int32;
}

def increment(n : int32) : int32 {
  return add_int32(n, 1);
}

def main() {
  let n : int32 = 5;
  let m : int32 = increment(n);
}

When modules are implemented, a wrapper around these intrinsic functions would be bundled in the standard library and included in the prelude.

Implement simple runtime variable declarations

So far the language has basic types, so the next step is to add variable declarations. These would be

let a = 1;

either a or 1 could be annotated with a type:

-- annotating the identifier
let a : int64 = 1;

-- annotating the expression
let a = 1 : int64;

It shouldn't matter, since both of these representations should be desugared into the same intermediate representation.

Implement primitive types

Render:

type My8BitData = prim 8;

With #8, all primitive types could be defined in the standard library using type aliases. This idea was inspired heavily by how Julia handles primitive types.

Nominal typing will also hopefully be supported using a data keyword, instead of the type keyword. So an Int64 and a Float64 could be two distinct types:

data Int64 = prim 64;
data Float64 = prim 64;

I'm not too sure how this will work with numeric literals, but they will probably have to be some sort of compiler intrinsic.

Implement constant definitions

These would be similar to variable declarations, except they use the def keyword, and can be used to define named functions.

-- compile-time constant declaration
def one : int64 = 1;

-- named function definition
def get_one() : int64 {
  return one;
}

This would pave the way to creating a main function:

def main() {
  def const : int64 = 3;
  let val : int64 = const;
}

Migrate from C code generation to LLVM code generation

C is a great, but it is tricky to compile to since all the tools must be written from the ground up. Compiling to LLVM will have a difficult learning curve, but there are plenty of frameworks and documentation out there that make it a little nicer.

Compiler Rewrite

There is a bit of technical debt, so I would like to tidy things up.

Junk drawer

A large collection of rough ideas that may or may not appear in the language.

let a = Vec2::new(3, 2);
let b = Vec2::new(1, 4);
let c = a.add(b); -- Vec2::add(a, b);

const (~+) = Vec2::add;

const (~.) = fn(a : Vec2, b : Vec2) : i32 {
  a.x * b.x + a.y * b.y
};

let c' = a ~+ b;

const math = import "core/math";
const M = math.Matrix2;
const (%*%) = M::mul;

let q = M::identity();
let r = M::identity();
let s = q %*% r;

liking the idea of having abstract data types
liking the idea of structural typing
liking the idea of a panic..catch syntax for exceptions (make it hard to recover)
liking the idea of extension functions

def Abstract = package int as T {
  def zero = 0 : T;
  def one = 1 : T;
  def add = fun(a : T, b : T) : T {
    a + b
  };
};

def two = unpack Abstract as T {
  T::one T::add T::one
};









def Player = struct {
  x : f32;
  y : f32;
  name : str;
};
let player : Player = struct.{
  x = 0;
  y = 0;
  name = "frank";
};
player.{
  x += 4.0;
  y += 9.5;
};
player::hi()::hello()::what()

def Id = [a : type] => (x : a) => a;

def (-) = [a : type] => (x : a) => match x {
  n : i32, m : i32 = #minus(n, m);
  n : i32          = #neg(n);
  _                = #compiler_error();
};

-- (-) : [a : type] -> a -> a





-- NEW

-- i don't like this v
-- identifiers depend on whitespace to determine precedence
let $  = 3;
let $$ = 300;
if $$ > 100 and $ < 40 {
  -- parses perfectly fine! >, <, and "and" are *weak* binary operators
  -- (and (> ($$) 100) (< ($) 40))
}
if $$>100and $< 40 {
  -- also parses fine, but differently
  -- $$> is a unary prefix operator
  -- and is a unary postfix operator
  -- $< is a weak binary operator
}

-- pointers:
let a = `3;
let b : i8 = a`; -- deref

let c = !(@(condition));




const fmt = import "fmt";
const printf = fmt.printf;
const (++) = fmt.(++);

-- what i like
-- go interfaces
-- c++ templates
-- zig zen
-- rust move semantics
-- haskell operators


def Set = type; -- Set : type#2

-- i would love to be able to implement thunks like ruby does

let a = 3;
core::each[i32](array) |x| {
  io::print(a); -- this would reference the `a` from the outer scope
                -- without needing to have closures
};

-- possible syntax
def core::each = [a]fn(arr : List[a]) |a| nothing : nothing {
  -- implementation
};

-- c++ templates
def fact = [n : usize]match n {
  0, 1 => 1,
  m    => m * fact[m - 1]
}; -- fact : [usize] -> usize

-- function types
-- core::each : [a : type] -> fn(List[a]) |a| nothing -> nothing




-- existential types
type Show = interface {
  show : fn(self) -> String;
};




-- parametric polymorphism
let id = [T]fn(x : T) : T { x };


perhaps have it so that functions can be used unary e.g.

let print_int = fn(x : i32) : () {
  ...
}

print_int 3 -- equivalent to print_int(3)

type digit = uint where _ < 10;

let hundred : uint = 100;
let mut nine : digit = 9;
nine = hundred as digit; -- a runtime check is performed

for m {
  -- while loop
}

for m in [1, 2, 3] {
  -- iterator
}

for {
  -- infinite loop
}

if m {

}

{
  -- block
}

typename alias = TypeName::A

typename PositiveInt = i32 where it > 0

typename Pos = [T subtype Numeric](x : T, y : T)

typename Digit = u8 where {
  it >= 0 and it <= 9
}

let pos : Pos[T] = (1, 2)

typename Arg1 = (a : int, b : int)
typename Arg2 = (int, int, int)
def function = fn(arg : Arg1 | Arg2) : unit {
  match arg {
    (a, b) : Arg1 => {
      ...
    },
    (a, b, c) : Arg2 => {
      ...
    }
  }
  return ()
}

function(a = 3, b = 4);
function(6, 7, 8);

def `-` = fn(arg : (int, int) | int) : int {
  match arg {
    n : int, m : int = #int_subtract(n, m)
    n : int          = #int_negate(n)
  }
}

def `+` = [T : Add]fn(a : T, b : T) {
  a.add(b)
}

Add strings to the language.

Currently strings wont be available as runtime values, but the framework should be included since #9 requires a string literal. Alternatively, extern could use identifiers, such as:

extern internal {
  -- import internal compiler functions, most likely wrappers around LLVM features
}

extern C {
  -- import stuff from C language
}

Add type aliases

Type aliases would be a nice thing to figure out early on. These would use the type keyword, and allow for an identifier to be given to a more complex type:

type Byte = uint8;

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.