sprint*, variadic append works correctly now.

This commit is contained in:
Ginger Bill
2017-01-29 21:29:10 +00:00
parent 43be91bca3
commit 9e143a38ce
3 changed files with 31 additions and 291 deletions

View File

@@ -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
foo :: proc() -> [dynamic]int {
x: [dynamic]int;
append(^x, 2, 3, 5, 7);
return x;
}
// 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 {
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
}

View File

@@ -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;

View File

@@ -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: {