This project aims to make a programming language that's a hybrid of JS(or TS), C(and some other stuff I like), Rust and Python. I had the idea since JS was C like anyways, and I like a lot of the things JS does even though I disagree with other ideas. Also, since JS compilers kind of exist, it didn't sound too hard to make a simpler one. Some goals are simplicity, one pass nature, ease of typing, and decent modern features.
The current name is temporary; these are a few other names I thought of: Luca, Mince, Letscript, Trip and K
-
Reduce LOC to write while also being a native language with native performance
- Citing Rust, C++, and C. The LOC for many things in these languages is incredible.
-
Compiles to assembly through every stage
- Targetting Windows first, Mac next, and then Linux.
-
Looks clean, and the syntax is simple and easy to get into
-
Not too hard to get into for JS or Python people, maybe can be used for transition from learning C with a JS bg or vice versa.
-
Lanugage Design:
- Parsable in a single pass, no need to backtrack or anything
- NONVERBOSE as much as possible, but never making anything confusing or ambiguous
- Be familiar to users of other languages
- Easy to type, easy to read
- I plan to incorporate support for JSON and JS Objects as dicts
-
Language Syntax:
- Only postfix, binary, and tertiary ops (F for unary, no +val or &val)
- It's to fix things like
a ++++++ b
((a ++) + (++ b)
, is also hard to parse), still leavesa +++ b
((a ++) + b
) possible but oh well.. and easier to parse either way
- It's to fix things like
{}
can be exchanged for-> expr
- If the block takes a return statement, like inside of a function (for things like
if
s) or in a function definition(fn fname() => 3
), it is used as the return.
- If the block takes a return statement, like inside of a function (for things like
;
s are optional when making a single statement in a line.
- Only postfix, binary, and tertiary ops (F for unary, no +val or &val)
-
Some Ideas I have about the lanugage:
- Objects and structs are synonymous
- Thus, structs aren't structs like they are in C, but actually dictionaries. I'll probably add a method to convert it to a buffer with the proper ordering and structure for C structs.
- I don't get why structs and tuples are differentiated so much in other languages, even though they're very similar(Tuples just have number keys). I'm just going to add special syntax for structs to behave like tuples in other langs, thinking of
obj<type1, type2, type3>
instead ofobj<a: type1>
and accessing it will be like in rust,obj.0
orobj[0]
- Unlike in JS, arrays won't have a dictionary attacted to them and will be properly differentiated.
- Array types can only be declared as
type[]
despite requiring objects to beobj<key: type>
- Array types can only be declared as
- Objects and structs are synonymous
let a = u16(1) // ; optional
let b = u8(1000); // Compile time error: 1000 > u8 max
let c = u32(2.0e10); // yes
let d = 'c'u16 // u16, but converted from char so treated the same lol
let e = 'abcd' // Combines the utf8 values together into a number and puts it in to an int type for now. Complains if it's too big
let f = "hi" // All strings allocated on the stack
fn features(): number {
let a = 10
let b = 2
if a < 9 -> panic()
else if a == 10 -> print("%d", b) // for the first stages, we're just going to use clib printf
// if statements are expressions, so you can do this, but you cannot close off individual branches with ; inside them
// Statement inside expressions are treated differently, as ; means you're ending the expression, which also cuts off the rest of the statement
while a ->
if b > 200 -> break
else b *= 2;
let c =
if a < 9 -> panic()
else if a < 10 -> 10
else 20;
// you can also kind of make some crazy looking statements, but it's still readable from left to right (imo)(until you get to the else's). obv, like all code, if you format and indent it properly, it's much better
for d in 0..20 -> if a % 2 == 0 -> a *= if a.to_string().len > 1 -> -2 else 1 else print("%d", a);
if a + b < 100 {
// you can also have scopes or something lol
print("too big")
panic()
}
if comparison(a, b) -> b
else a
}
// Generic function works for all numbers. Equivalent to fn comparison (a number, b number)
fn comparison(a, b) -> a > b
fn typeandreturn(): number -> 4;
return features(); // return opcode for program
/* Non features in Stage 1:
Strings, heap alloc, arrays, structs, objects, traits and ptrs.
Oh yeah, you won't be yelled at for leaving out comment closer at the end of the file
- Straight up assembly generation for all of that (although not the fastest assembly generation :P)
- VERY powerful generics and compiler conversions etc
- Introduces Errors
- Introduces JS Objects (dicts)
- Corresponding type:
object
- and their derivative, Arrays
- Corresponding type:
array
- Corresponding type:
- Corresponding type:
- Introduces Traits
- Defines a type of interface for types and
- Introduces Structs, which are actually similar to classes and objects in JS, but can only set defined members and accessing undefined members results in an error
- Can use strings to access members too.
- Has to be wrapped in error handling
obj["x"]?
- Has to be wrapped in error handling
- Can use strings to access members too.
// Heap allocated array
let hi = []
hi.reduce((a, b) => a + b) // which has traits implemented internally, also anon funcs!!
let yes = str[].new() // Allocates an array of strings
let yes2 = array<str>.new()
let v = "string" // Heap allocated string, dk how heap allocation is going to work but we will have it :D
// Strings will implicitly store length and will function like arrays, similar to JS. Will hopefully be UTF-8 but we'll see ;-;
// OBJECTS POG
let obj = { bruh: "ez" };
// defines a struct
struct hello {
hi: str; bruh: str?; yes: u32, no;// In multi var declarations(with ,), the type of the first member's type is assumed for succeeding vars
new() -> hello { hi: "bruh" }
}
trait greeting { print(self) }
impl greeting for hello {
print(self) -> print("hello " + )
}
hello.new().print() //
fn func(hi: str) -> print(hi + " world")
func("hello ")
/* Added features in Stage 2:
Strings and arrays, which are similar to structs but structs aren't here yet so lol
- Planned main focuses:
- Modules
- Packages
- Compiler speed
- Hot Reload
// hello.jsc
fn hello({ lol }/* Implicit typing: Object { lol: any } */) -> print(lol);
hello { lol: 30 }
export hello;
// main.jsc
import hello from "hello.jsc" // Works like node, executes all of the code in hello then proceeds to do it here
- https://dart.dev/samples
- https://github.com/vlang/v/blob/master/examples/mini_calculator.v
- Tutorial
- Windows Calling Conventions:
- COOL OPTIMIZATIONS POG: https://www.youtube.com/watch?v=VMpSYJ_7aYM
- Malloc in NASM on windows:
- Academic references:
- Different assembly syntaxes: