[WIP] Syntax proposal for CompilerV0
Opened this issue ยท 31 comments
It's largely based on Rust but simplified.
Variable declaration
let a : int = 1;
- Done?
or for constants:
const b : string = "hello";
- Done?
Reassignment
let a : int = 2;
a = "hello"; // wrong! type mismatch
a = 5; // sounds good
const b : bool = true;
b = false; // wrong! b is constant
- Done?
Simple math
let a : bool = 1 + 2 == 3;
- Done?
If-statements
if (condition) {
// code...
}
- Done?
or, with another branch:
if (condition) {
// code...
} else if (another_condition) {
// code...
} else {
// code...
}
- Done?
Switch cases
let num : int = 25;
// can also be written switch num { ...
switch (num) {
case 25 {
// do stuff
}
case 30, 40 {
// do stuff if num is 30 or 40
}
case (25, 30, 35) {
// can also use parens
}
default {
}
}
- Done?
Loops
While
while (true) {
// do a thing
}
- Done?
For
for (let x : int = 0; x < 10; x += 1) {
// do a thing
}
- Done?
Functions
func add_two_numbers (a : int, b : int) : int {
return a + b;
}
- Done?
Structs
struct Slice {
buffer : byte*,
size : int
};
- Done?
Tell me what our default language is so that we can minimize such issues :)
@akkartik default language? Do you mean the sort of basis parent language whose syntax we are simplifying?
Yes, it shall be Rust. :)
I've decided to revert to C-style while
and for
loops because we do not have iterators or anything fancy that Rust-style "requires".
Still not hooked on having :=
as our assignment operator :/
How do you feel about set a = 5;
?
Or we could go the route of normal a = 5
.
Thoughts on let
/const
vs let
/let mut
?
if (set a = read()) { ... }
??
@KCreate are you suggesting that it should be required in loops to use the word set
?
No, I think requiring set
at all is a bad idea
I'd say we'll go for the normal way (a = 5
).
Regarding let
/const
vs let
/let mut
, I'd prefer let/const
.
let mut
makes mut
look like some kind of attribute.
Does Rust have :=
?
Well then, let's follow Rust :)
I notice your conditional and loop examples above use parens:
if (condition) {
// code...
} else if (another_condition) {
// code...
} else {
// code...
}
Let's just follow Rust exactly:
if condition {
// code...
} else if another_condition {
// code...
} else {
// code...
}
Just added syntax for a switch
statement
How easy do we want this first compiler to be? I don't know how we're weighing that against number of features / ease of implementing another language in this compiled one, but I think that should be discussed at some level of technical detail.
I'd go for C level simplicity, maybe even less.
I've added syntax highlighting using the swift
tag.
Also some other points:
- Do we want typedefs or should everything be in one namespace?
- Do we want a certain level of oop? (Even if it's just syntax sugar)
I'd say no to the second one but don't know enough / can't think enough at the moment to offer an opinion on namespacing.
What should be the syntax to create pointer types?
I'd suggest type*
Only if we make it left-associative. I have severe issues with people who write C-style pointers like that:
int* a, b; // misleading! only a is a pointer
What about making it right-associative?
*int
that is.
Are there languages who have a different pointer syntax?
Then it's kind of annoying for dereferencing. I think keeping it C/Rust like in form makes sense, but changing the associativity would be a strong preference.
Why would that interfere with dereferencing?
BTW, what's rust's pointer syntax?
Since traditionally dereferencing has used that exact syntax. Rust is (very nearly) the same as C.
Our syntax is context free so I don't think we'll have to worry about that.
How about switching the meaning of *
and &
?
let foo : *int; // pointer to int
*test; // pointer to variable test
&test; // dereference test
Hard veto on that. Very confusing. We don't have to worry about it at a technical level, sure, but as someone who TAs students quite regularly... they already get confused with the dual meaning of *
in C/C++. This would not help.
I see. I however don't see a problem with using the *int
syntax.
We know exactly in our syntax when the type grammar has to kick in, so it can't be confused with the dereference operator.
let a : *int = ...;
^
|
+- The parser knows it has to parse this expression as a type.
tmp = 5 *int;
^
|
+- This is "5 times int", where int would be a semantic error as it's a reserved name.
Yeah that's fine, I think; I merged that intro master.