The common C langugage is developed to deliver the performance of natively compiled languages whilst maintaining the ease of memory management without workarounds like garbage collection and borrow checkers. Common C is object oriented and statically typed.
Common C will be targeting both x86_64 for Intel and AMD aswell as .NET (CIL).
Currently the .NET target is under development, with the x86_64 target to be developed as soon as the .NET target is satisfactory.
Contributions are welcome with open arms!
Other languages are either easy to write, but perform poorly (E.g Python, JavaScript, etc) or they perform well but are difficult to write (E.g C, C++, Rust, etc). Common C is designed to be easy to write and perform well without workarounds like garbage collection and borrow checkers.
The philosophy behind the syntax is to be easily readable and writable. Syntax is developed so that the shortest combination of keystrokes produces functionality. We keep in mind that not every developed posesses giant hands that reach across the keyboard.
An example of this is using log as the standard output function. C# uses Console.WriteLine and Rust uses println!. Both of these are long to write and require more keystrokes than simply log.
Unpacking tables has never been easier! Here is an example of unpacking a table in Common C:
// array = { "Hello", "there", "world!", "I'm", "a", "machine", "with", "finite", "possibilities!" }
log(array->3..5)
// I'm a machineHere we are unpacking the array from index 3 to index 5 and logging it to the console.
Common C uses top-level, global and public declarations for functions, structs and globals - meaning everything can be accessed from anywhere. Given CommonC's ergonomic style, it has been decided that having access to everything anywhere is the "free-est" way of programming. You do not have to declare the visibility of user-types like functions and globals. The only exception is uninitialized user-types like struct declarations.
There really is no point in using var or equal in a modern, statically typed language apart from extra syntax clutter - hence the type is directly stated instead.
Semicolon after statements is optional simply because some people prefer it, though it has no function.
Table of contents
- Expressions
- String
- Primitive type string.
- Boolean
- Primitive type boolean.
- Number
- Primitive type number.
- Identifier
- Generic identifiers.
- Array
- Unbound, typeless array.
- Array initializer
- Bound, typed array initializer.
- Index
- Index of array.
- Length
- Length of array.
- Range
- Range between two expressions.
- Call
- Function call.
- Member
- Parent / member relationship.
- Relational
- Equals.
- Not equals.
- Greater than.
- Greater than or equals.
- Less than.
- Less than or equals.
- Arithmetic
- Addition.
- Subtraction.
- Multiplication.
- Division.
- Modulus.
- Power.
- Left shift.
- Right shift.
- Negate
- Negate expression from positive to negative.
- Not
- Reverse boolean.
- Object initializer
- Bound, typed object initializer.
- Parameter
- Function declaration parameter.
- Parenthesized
- Parenthesized expression for control flow.
- Type
- Native, reserved types.
- Unpack
- Unpacking arrays.
- String
- Statements
- Assignment
- Variable assignments.
- Function call
- Declared function call.
- Closure
- Closure to determine control flow.
- For loop
- Conditional, numeric loop.
- Function declaration
- Top-level function declaration.
- Return
- Returns a function.
- Struct
- Structural user-type.
- Variable declaration
- Local and global declaration.
- While
- Conditional loop.
- If
- Conditional control flow.
- Use
- Imports file, parses it into an AST and merges it with the main file.
- Assignment
Generic string taking any character. Starts with a quotation mark and terminates with a quotation mark.
"<any>"Example
"Hello, world!"
Deterministic boolean.
true / falseExample
bool isTrue = true
Any number of any length.
123
Example
person.age = 50Generic identifier starting with a letter and containing letters or numbers.
someVariable
Example
log(yourName)An array of expression, seperated by a comma.
{ <expr[]> }
Example
{ 5, 10, 15 }Initializes a new array with specified type and size. Each item in the initialized array is seperated by a comma.
<expr | type>[<expr | number>] {
<expr[]>
}
Example
int[3] { 5, 10, 15 }Accesses an array through a specified index.
<expr | array<any>>[<expr>]
Example
int arr = int[3] { 5, 10, 15 }
log(arr[1])Gets the length of an array.
#<expr>
Example
#arrPerforms a call on the given function. Arguments are seperated by a comma.
<expr>(<expr[]>)
Example
log("Hello, world!")Accesses the member of a parent. Parent and member are seperated by a dot. Can be nested.
<expr>.<expr>
Example
Parent.memberDetermines wether two expressions meet a conditional and their relation to eachother.
Supported operators
==- Equals.!=- Not equals.>- Greater than.>=- Greater than or equals.<- Less than.<=- Less than or equals.
<expr> <operator> <expr>
Example
4 > 2Performs an arithmetic operation on two expressions.
Supported operators
+- Addition.-- Subtraction.*- Multiplication./- Division.^- Power.%- Modulus.
<expr> <operator> <expr>
Example
2 + 2Changes an expression to its additive inverse.
-<expr>
Example
-100Changes a number or boolean to its binary counterpart.
!<expr>
Example
!true
Initializes a new object of a specified type. Properties of the object can be assigned, with name and value seperated by a colon and each property seperated by a comma.
<expr | type> {
<expr>: <expr>,
}
Example
Person {
name: "Kai",
age: 26
}
The parameter structure used in function declarations.
<expr | type> <expr>
Example
str name
Wraps an expression in parentheses to override syntax precedence.
(<expr>)
Example
(2 + 2) * 5
Primitive reserved types.
Supported types
str|stringi8u8i16u16i32u32i64u64i128u128f32f64boolfn
<type>
Example
i32Unpacks an array into seperate components.
<expr> | array<any>> -> <expr | range>
Example
arr -> 0..5Assigns an expression to a local, global or property
<expr> = <expr>
Example
message = "Hello!"Calls a function and, if the return type is not fn, returns it.
<expr>(<expr>)
Example
log("Hello, world!")Creates a new closure for control flow purposes.
{ <statements> }
Example
{ log("Hello, world!") }
Repeats a closure until numeric range has been nivelled. Sets the current iteration to a user-specified local.
for <expr | range>, <expr | identifier> {
<statements>
}
Example
for 0..5, i {
log(i)
}Declares a new function with parameters and a return type. Parentheses for parameters is not needed if there are none.
<expr | type> <expr | identifier>(<parameters>) {
<statements>
}
Example
fn testFunc(str message) {
log(message)
}
fn main {
testFunc("Hello, world!")
}Returns an expression and exits the function immediately.
return <expr>
Example
return trueDeclares a new struct object with user-defined properties. Properties are seperated by a comma and cannot be assigned a default value.
struct <expr | identifier> {
<expr | type> <expr | identifier>,
}
Example
struct Person {
str name,
i32 age
}Declares a new variable. If the declaration is in a closure, it will become a local. If the variable is declared on the global scope, it will become a global. Declarations do not require a default value.
<expr | type> <expr | identifier> = <expr>
Example
str message = "Hello, world!"Repeats a closure until the condition is met.
while <expr> {
<statements>
}
Example
while true {
log("To infinity...")
}Branches to closure if condition is met. If main condition is not met, checks elseifs and lastly the else case.
if <expr> {
<statements>
}
elseif <expr> {
<statements>
}
else {
<statements>
}
Example
if 2 == 2 {
log(4)
}Adds a .coc extension, imports the file from the name in the specified working directory, parses its syntax and merges it with the main file.
use <expr | identifier>
Example
use math