2
0
Эх сурвалжийг харах

sprint*, variadic append works correctly now.

Ginger Bill 8 жил өмнө
parent
commit
9e143a38ce
3 өөрчлөгдсөн 31 нэмэгдсэн , 291 устгасан
  1. 5 280
      code/demo.odin
  2. 19 0
      core/fmt.odin
  3. 7 11
      src/ir.c

+ 5 - 280
code/demo.odin

@@ -1,288 +1,13 @@
 #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() {
-	array: [dynamic]int;
-	defer free(array);
-	reserve(^array, 10);
-
-	append(^array, 2, 3, 5, 7, 11, 13);
-	for val, idx in array {
-		fmt.println(val, idx);
-	}
-}
-
-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
+	foo :: proc() -> [dynamic]int {
+		x: [dynamic]int;
+		append(^x, 2, 3, 5, 7);
+		return x;
 	}
 
-	for val, idx in 12..<16 {
-		fmt.println(val, idx);
-	}
-
-	primes := [...]int{2, 3, 5, 7, 11, 13, 17, 19};
-
-	for p in primes {
+	for p in foo() {
 		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
 }

+ 19 - 0
core/fmt.odin

@@ -255,6 +255,25 @@ bprintln :: proc(buf: ^Buffer, args: ...any) -> int {
 	return buf.length;
 }
 
+sprint :: proc(buf: []byte, args: ...any) -> string {
+	b: Buffer;
+	b.data = buf;
+	count := bprint(^b, ...args);
+	return cast(string)b.data[:b.length];
+}
+sprintln :: proc(buf: []byte, args: ...any) -> string {
+	b: Buffer;
+	b.data = buf;
+	count := bprintln(^b, ...args);
+	return cast(string)b.data[:b.length];
+}
+sprintf :: proc(buf: []byte, fmt: string, args: ...any) -> string {
+	b: Buffer;
+	b.data = buf;
+	count := bprintf(^b, fmt, ...args);
+	return cast(string)b.data[:b.length];
+}
+
 
 is_type_string :: proc(info: ^Type_Info) -> bool {
 	using Type_Info;

+ 7 - 11
src/ir.c

@@ -3035,9 +3035,6 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
 					isize arg_index = 0;
 					isize arg_count = 0;
 					for_array(i, ce->args) {
-						if (i == 0) {
-							continue;
-						}
 						AstNode *a = ce->args.e[i];
 						Type *at = base_type(type_of_expr(proc->module->info, a));
 						if (at->kind == Type_Tuple) {
@@ -3046,6 +3043,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
 							arg_count++;
 						}
 					}
+
 					irValue **args = gb_alloc_array(proc->module->allocator, irValue *, arg_count);
 					bool vari_expand = ce->ellipsis.pos.line != 0;
 
@@ -3078,8 +3076,8 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
 						if (slice_len > 0) {
 							irValue *base_array = ir_add_local_generated(proc, make_type_array(a, elem_type, slice_len));
 
-							for (isize i = 1, j = 0; i < arg_count; i++, j++) {
-								irValue *addr = ir_emit_array_epi(proc, base_array, j);
+							for (isize i = 1; i < arg_count; i++) {
+								irValue *addr = ir_emit_array_epi(proc, base_array, i-1);
 								ir_emit_store(proc, addr, args[i]);
 							}
 
@@ -4220,7 +4218,8 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir
 			val = ir_emit_load(proc, ir_emit_ptr_offset(proc, elem, idx));
 		} break;
 		case Type_DynamicArray: {
-			irValue *elem = ir_dynamic_array_elem(proc, expr);
+			irValue *elem = ir_emit_struct_ep(proc, expr, 0);
+			elem = ir_emit_load(proc, elem);
 			val = ir_emit_load(proc, ir_emit_ptr_offset(proc, elem, idx));
 		} break;
 		default:
@@ -4789,14 +4788,11 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 			} break;
 			case Type_DynamicArray: {
 				irValue *count_ptr = NULL;
-				irValue *array = ir_build_expr(proc, rs->expr);
+				irValue *array = ir_build_addr(proc, rs->expr).addr;
 				if (is_type_pointer(type_deref(ir_type(array)))) {
-					count_ptr = ir_emit_struct_ep(proc, array, 1);
 					array = ir_emit_load(proc, array);
-				}  else {
-					count_ptr = ir_add_local_generated(proc, t_int);
-					ir_emit_store(proc, count_ptr, ir_dynamic_array_count(proc, array));
 				}
+				count_ptr = ir_emit_struct_ep(proc, array, 1);
 				ir_build_range_indexed(proc, array, val_type, count_ptr, &val, &index, &loop, &done);
 			} break;
 			case Type_Slice: {