Browse Source

Update README.md

Ginger Bill 8 years ago
parent
commit
ec9c8fb8a4
4 changed files with 578 additions and 22 deletions
  1. 19 18
      README.md
  2. 1 1
      build.bat
  3. 276 3
      code/demo.odin
  4. 282 0
      code/old_demos/demo005.odin

+ 19 - 18
README.md

@@ -2,7 +2,7 @@
 
 # The Odin Programming Language
 
-Odin is fast, concise, readable, pragmatic and open sourced. It is designed with the intent of replacing C with the following goals:
+The Odin programming language is fast, concise, readable, pragmatic and open sourced. It is designed with the intent of replacing C with the following goals:
 * simplicity
 * high performance
 * built for modern systems
@@ -18,6 +18,7 @@ Odin is fast, concise, readable, pragmatic and open sourced. It is designed with
 * [Composition & Refactorability](https://www.youtube.com/watch?v=n1wemZfcbXM)
 * [Introspection, Modules, and Record Layout](https://www.youtube.com/watch?v=UFq8rhWhx4s)
 * [push_allocator & Minimal Dependency Building](https://www.youtube.com/watch?v=f_LGVOAMb78)
+* [when, for, & procedure overloading](https://www.youtube.com/watch?v=OzeOekzyZK8)
 
 ## Requirements to build and run
 
@@ -30,27 +31,27 @@ Odin is fast, concise, readable, pragmatic and open sourced. It is designed with
 ## Warnings
 
 * This is still highly in development and the language's design is quite volatile.
-* Syntax is definitely not fixed
+* Syntax is not fixed.
 
 ## Roadmap
 
 Not in any particular order
 
-* Custom backend to replace LLVM
-	- Improve SSA design to accommodate for lowering to a "bytecode"
-	- SSA optimizations
-	- COFF generation
-	- linker
-* Type safe "macros"
-* Documentation generator for "Entities"
-* Multiple architecture support
-* Inline assembly
-* Linking options
-	- Executable
-	- Static/Dynamic Library
-* Debug information
+* Compile Time Execution (CTE)
+	- More metaprogramming madness
+	- Compiler as a library
+	- AST inspection and modification
+* CTE-based build system
+* Replace LLVM backend with my own custom backend
+* Improve SSA design to accommodate for lowering to a "bytecode"
+* SSA optimizations
+* Parametric Polymorphism ("Generics")
+* Documentation Generator for "Entities"
+* Multiple Architecture support
+* Language level atomics and concurrency support
+* Debug Information
 	- pdb format too
-* Command line tooling
-* Compiler internals:
+* Command Line Tooling
+* Compiler Internals:
 	- Big numbers library
-
+	- Multithreading for performance increase

+ 1 - 1
build.bat

@@ -4,7 +4,7 @@
 set exe_name=odin.exe
 
 :: Debug = 0, Release = 1
-set release_mode=0
+set release_mode=1
 set compiler_flags= -nologo -Oi -TC -fp:fast -fp:except- -Gm- -MP -FC -GS- -EHsc- -GR-
 
 if %release_mode% EQU 0 ( rem Debug

+ 276 - 3
code/demo.odin

@@ -1,9 +1,282 @@
 #import "fmt.odin";
+#import "utf8.odin";
+// #import "atomic.odin";
+// #import "hash.odin";
+// #import "math.odin";
+// #import "mem.odin";
+// #import "opengl.odin";
+// #import "os.odin";
+// #import "sync.odin";
+// #import win32 "sys/windows.odin";
 
 main :: proc() {
-    fmt.println(foo("FOO"));
+	// syntax();
+	procedure_overloading();
 }
 
-foo :: proc(test: string, test1: string, args: ...any) {  }
+syntax :: proc() {
+	// Cyclic type checking
+	// Uncomment to see the error
+	// A :: struct {b: B};
+	// B :: struct {a: A};
 
-foo :: proc(test: string) { }
+	x: int;
+	y := cast(f32)x;
+	z := transmute(u32)y;
+	// down_cast, union_cast are similar too
+
+
+
+	// Basic directives
+	fmt.printf("Basic directives = %s(%d): %s\n", #file, #line, #procedure);
+	// NOTE: new and improved `printf`
+	// TODO: It does need accurate float printing
+
+
+
+	// record fields use the same syntax a procedure signatures
+	Thing1 :: struct {
+		x: f32,
+		y: int,
+		z: ^[]int,
+	};
+	Thing2 :: struct {x: f32, y: int, z: ^[]int};
+
+	// Slice interals are now just a `ptr+count`
+	slice: []int; compile_assert(size_of_val(slice) == 2*size_of(int));
+
+	// Helper type - Help the reader understand what it is quicker
+	My_Int  :: type int;
+	My_Proc :: type proc(int) -> f32;
+
+
+	// All declarations with : are either variable or constant
+	// To make these declarations syntactically consistent
+	v_variable := 123;
+	c_constant :: 123;
+	c_type1    :: int;
+	c_type2    :: []int;
+	c_proc     :: proc() { /* code here */ };
+
+
+	x += 1;
+	x -= 1;
+	// ++ and -- have been removed
+	// x++;
+	// x--;
+	// Question: Should they be added again?
+	// They were removed as they are redundant and statements, not expressions
+	// like in C/C++
+
+
+	// You can now build files as a `.dll`
+	// `odin build_dll demo.odin`
+
+
+	// New vector syntax
+	u, v: [vector 3]f32;
+	v[0] = 123;
+	v.x  = 123; // valid for all vectors with count 1 to 4
+
+	// Next part
+	prefixes();
+}
+
+
+Prefix_Type :: struct {x: int, y: f32, z: rawptr};
+
+thread_local my_tls: Prefix_Type;
+
+prefixes :: proc() {
+	using var: Prefix_Type;
+	immutable const := Prefix_Type{1, 2, nil};
+	var.x = 123;
+	x = 123;
+	// const.x = 123; // const is immutable
+
+
+
+	foo :: proc(using immutable pt: Prefix_Type, immutable int_ptr: ^int) {
+		// int_ptr = nil; // Not valid
+		int_ptr^ = 123; // Is valid
+	}
+
+
+
+	// Same as C99's `restrict`
+	bar :: proc(no_alias a, b: ^int) {
+		// Assumes a never equals b so it can perform optimizations with that fact
+	}
+
+
+	when_statements();
+}
+
+
+
+
+
+when_statements :: proc() {
+	X :: 123 + 12;
+	Y :: X/5;
+	COND :: Y > 0;
+
+	when COND {
+		fmt.println("Y > 0");
+	} else {
+		fmt.println("Y <= 0");
+	}
+
+
+	when false {
+		this_code_does_not_exist(123, 321);
+		but_its_syntax_is_valid();
+		x :: ^^^^int;
+	}
+
+	foreign_procedures();
+}
+
+#foreign_system_library win32_user "user32.lib" when ODIN_OS == "windows";
+// NOTE: This is done on purpose for two reasons:
+// * Makes it clear where the platform specific stuff is
+// * Removes the need to solve the travelling salesman problem when importing files :P
+
+foreign_procedures :: proc() {
+	ShowWindow  :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #foreign win32_user;
+	show_window :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #foreign win32_user "ShowWindow";
+	// NOTE: If that library doesn't get used, it doesn't get linked with
+	// NOTE: There is not link checking yet to see if that procedure does come from that library
+
+	// See sys/windows.odin for more examples
+
+	special_expressions();
+}
+
+special_expressions :: proc() {
+	// Block expression
+	x := {
+		a: f32 = 123;
+		b := a-123;
+		c := b/a;
+		give c;
+	}; // semicolon is required as it's an expression
+
+	y := if x < 50 {
+		give x;
+	} else {
+		// TODO: Type cohesion is not yet finished
+		give 123;
+	}; // semicolon is required as it's an expression
+
+
+	// This is allows for inline blocks of code and will be a useful feature to have when
+	// macros will be implemented into the language
+
+	loops();
+}
+
+loops :: proc() {
+	// The C-style for loop
+	for i := 0; i < 123; i += 1 {
+		break;
+	}
+	for i := 0; i < 123; {
+		break;
+	}
+	for false {
+		break;
+	}
+	for {
+		break;
+	}
+
+	for i in 0..<123 { // 123 exclusive
+	}
+
+	for i in 0...122 { // 122 inclusive
+	}
+
+	for val, idx in 12..<16 {
+		fmt.println(val, idx);
+	}
+
+	primes := [...]int{2, 3, 5, 7, 11, 13, 17, 19};
+
+	for p in primes {
+		fmt.println(p);
+	}
+
+	// Pointers to arrays, slices, or strings are allowed
+	for _ in ^primes {
+		// ignore the value and just iterate across it
+	}
+
+
+
+	name := "你好,世界";
+	fmt.println(name);
+	for r in name {
+		compile_assert(type_of_val(r) == rune);
+		fmt.printf("%r\n", r);
+	}
+
+	when false {
+		for i, size := 0; i < name.count; i += size {
+			r: rune;
+			r, size = utf8.decode_rune(name[i:]);
+			fmt.printf("%r\n", r);
+		}
+	}
+
+	procedure_overloading();
+}
+
+
+procedure_overloading :: proc() {
+	THINGF :: 14451.1;
+	THINGI :: 14451;
+
+	foo :: proc() {
+		fmt.printf("Zero args\n");
+	}
+	foo :: proc(i: int) {
+		fmt.printf("int arg, i=%d\n", i);
+	}
+	foo :: proc(f: f64) {
+		i := cast(int)f;
+		fmt.printf("f64 arg, f=%d\n", i);
+	}
+
+	foo();
+	foo(THINGF);
+	// foo(THINGI); // 14451 is just a number so it could go to either procedures
+	foo(cast(int)THINGI);
+
+
+
+
+	foo :: proc(x: ^i32) -> (int, int) {
+		fmt.println("^int");
+		return 123, cast(int)(x^);
+	}
+	foo :: proc(x: rawptr) {
+		fmt.println("rawptr");
+	}
+
+
+	a: i32 = 123;
+	b: f32;
+	c: rawptr;
+	fmt.println(foo(^a));
+	foo(^b);
+	foo(c);
+	// foo(nil); // nil could go to numerous types thus the ambiguity
+
+	f: proc();
+	f = foo; // The correct `foo` to chosen
+	f();
+
+
+	// See math.odin and atomic.odin for more examples
+}

+ 282 - 0
code/old_demos/demo005.odin

@@ -0,0 +1,282 @@
+#import "fmt.odin";
+#import "utf8.odin";
+// #import "atomic.odin";
+// #import "hash.odin";
+// #import "math.odin";
+// #import "mem.odin";
+// #import "opengl.odin";
+// #import "os.odin";
+// #import "sync.odin";
+// #import win32 "sys/windows.odin";
+
+main :: proc() {
+	// syntax();
+	procedure_overloading();
+}
+
+syntax :: proc() {
+	// Cyclic type checking
+	// Uncomment to see the error
+	// A :: struct {b: B};
+	// B :: struct {a: A};
+
+	x: int;
+	y := cast(f32)x;
+	z := transmute(u32)y;
+	// down_cast, union_cast are similar too
+
+
+
+	// Basic directives
+	fmt.printf("Basic directives = %s(%d): %s\n", #file, #line, #procedure);
+	// NOTE: new and improved `printf`
+	// TODO: It does need accurate float printing
+
+
+
+	// record fields use the same syntax a procedure signatures
+	Thing1 :: struct {
+		x: f32,
+		y: int,
+		z: ^[]int,
+	};
+	Thing2 :: struct {x: f32, y: int, z: ^[]int};
+
+	// Slice interals are now just a `ptr+count`
+	slice: []int; compile_assert(size_of_val(slice) == 2*size_of(int));
+
+	// Helper type - Help the reader understand what it is quicker
+	My_Int  :: type int;
+	My_Proc :: type proc(int) -> f32;
+
+
+	// All declarations with : are either variable or constant
+	// To make these declarations syntactically consistent
+	v_variable := 123;
+	c_constant :: 123;
+	c_type1    :: int;
+	c_type2    :: []int;
+	c_proc     :: proc() { /* code here */ };
+
+
+	x += 1;
+	x -= 1;
+	// ++ and -- have been removed
+	// x++;
+	// x--;
+	// Question: Should they be added again?
+	// They were removed as they are redundant and statements, not expressions
+	// like in C/C++
+
+
+	// You can now build files as a `.dll`
+	// `odin build_dll demo.odin`
+
+
+	// New vector syntax
+	u, v: [vector 3]f32;
+	v[0] = 123;
+	v.x  = 123; // valid for all vectors with count 1 to 4
+
+	// Next part
+	prefixes();
+}
+
+
+Prefix_Type :: struct {x: int, y: f32, z: rawptr};
+
+thread_local my_tls: Prefix_Type;
+
+prefixes :: proc() {
+	using var: Prefix_Type;
+	immutable const := Prefix_Type{1, 2, nil};
+	var.x = 123;
+	x = 123;
+	// const.x = 123; // const is immutable
+
+
+
+	foo :: proc(using immutable pt: Prefix_Type, immutable int_ptr: ^int) {
+		// int_ptr = nil; // Not valid
+		int_ptr^ = 123; // Is valid
+	}
+
+
+
+	// Same as C99's `restrict`
+	bar :: proc(no_alias a, b: ^int) {
+		// Assumes a never equals b so it can perform optimizations with that fact
+	}
+
+
+	when_statements();
+}
+
+
+
+
+
+when_statements :: proc() {
+	X :: 123 + 12;
+	Y :: X/5;
+	COND :: Y > 0;
+
+	when COND {
+		fmt.println("Y > 0");
+	} else {
+		fmt.println("Y <= 0");
+	}
+
+
+	when false {
+		this_code_does_not_exist(123, 321);
+		but_its_syntax_is_valid();
+		x :: ^^^^int;
+	}
+
+	foreign_procedures();
+}
+
+#foreign_system_library win32_user "user32.lib" when ODIN_OS == "windows";
+// NOTE: This is done on purpose for two reasons:
+// * Makes it clear where the platform specific stuff is
+// * Removes the need to solve the travelling salesman problem when importing files :P
+
+foreign_procedures :: proc() {
+	ShowWindow  :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #foreign win32_user;
+	show_window :: proc(hwnd: rawptr, cmd_show: i32) -> i32 #foreign win32_user "ShowWindow";
+	// NOTE: If that library doesn't get used, it doesn't get linked with
+	// NOTE: There is not link checking yet to see if that procedure does come from that library
+
+	// See sys/windows.odin for more examples
+
+	special_expressions();
+}
+
+special_expressions :: proc() {
+	// Block expression
+	x := {
+		a: f32 = 123;
+		b := a-123;
+		c := b/a;
+		give c;
+	}; // semicolon is required as it's an expression
+
+	y := if x < 50 {
+		give x;
+	} else {
+		// TODO: Type cohesion is not yet finished
+		give 123;
+	}; // semicolon is required as it's an expression
+
+
+	// This is allows for inline blocks of code and will be a useful feature to have when
+	// macros will be implemented into the language
+
+	loops();
+}
+
+loops :: proc() {
+	// The C-style for loop
+	for i := 0; i < 123; i += 1 {
+		break;
+	}
+	for i := 0; i < 123; {
+		break;
+	}
+	for false {
+		break;
+	}
+	for {
+		break;
+	}
+
+	for i in 0..<123 { // 123 exclusive
+	}
+
+	for i in 0...122 { // 122 inclusive
+	}
+
+	for val, idx in 12..<16 {
+		fmt.println(val, idx);
+	}
+
+	primes := [...]int{2, 3, 5, 7, 11, 13, 17, 19};
+
+	for p in primes {
+		fmt.println(p);
+	}
+
+	// Pointers to arrays, slices, or strings are allowed
+	for _ in ^primes {
+		// ignore the value and just iterate across it
+	}
+
+
+
+	name := "你好,世界";
+	fmt.println(name);
+	for r in name {
+		compile_assert(type_of_val(r) == rune);
+		fmt.printf("%r\n", r);
+	}
+
+	when false {
+		for i, size := 0; i < name.count; i += size {
+			r: rune;
+			r, size = utf8.decode_rune(name[i:]);
+			fmt.printf("%r\n", r);
+		}
+	}
+
+	procedure_overloading();
+}
+
+
+procedure_overloading :: proc() {
+	THINGF :: 14451.1;
+	THINGI :: 14451;
+
+	foo :: proc() {
+		fmt.printf("Zero args\n");
+	}
+	foo :: proc(i: int) {
+		fmt.printf("int arg, i=%d\n", i);
+	}
+	foo :: proc(f: f64) {
+		i := cast(int)f;
+		fmt.printf("f64 arg, f=%d\n", i);
+	}
+
+	foo();
+	foo(THINGF);
+	// foo(THINGI); // 14451 is just a number so it could go to either procedures
+	foo(cast(int)THINGI);
+
+
+
+
+	foo :: proc(x: ^i32) -> (int, int) {
+		fmt.println("^int");
+		return 123, cast(int)(x^);
+	}
+	foo :: proc(x: rawptr) {
+		fmt.println("rawptr");
+	}
+
+
+	a: i32 = 123;
+	b: f32;
+	c: rawptr;
+	fmt.println(foo(^a));
+	foo(^b);
+	foo(c);
+	// foo(nil); // nil could go to numerous types thus the ambiguity
+
+	f: proc();
+	f = foo; // The correct `foo` to chosen
+	f();
+
+
+	// See math.odin and atomic.odin for more examples
+}