package builtin
-string :: #type []u8;
-cstring :: #type ^u8;
+str :: #type []u8;
+cstr :: #type ^u8;
+// CLEANUP: Remove the buffer type from builtin
Buffer :: #type []void;
// NOTE: Because of many implementation details, all fields of this
fd : FileDescriptor;
}
-open :: proc (file: ^File, path: string, mode := OpenMode.Read, flags := FDFlags.Sync) -> bool {
+open :: proc (file: ^File, path: str, mode := OpenMode.Read, flags := FDFlags.Sync) -> bool {
// Currently the directory's file descriptor appears to always be 3
DIR_FD :: 3;
return true;
}
-write :: proc (file: File, data: string) {
+write :: proc (file: File, data: str) {
vec := IOVec.{ buf = data.data, len = data.count };
tmp : Size;
fd_write(file.fd, IOVecArray.{ ^vec, 1 }, ^tmp);
return fs.size;
}
-get_contents_from_file :: proc (file: File) -> string {
+get_contents_from_file :: proc (file: File) -> str {
size := cast(u32) get_size(file);
data := cast(^u8) alloc(context.allocator, size);
get_contents :: proc {
get_contents_from_file,
- proc (path: string) -> string {
+ proc (path: str) -> str {
tmp_file: File;
- if !open(^tmp_file, path, OpenMode.Read) do return string.{ null, 0 };
+ if !open(^tmp_file, path, OpenMode.Read) do return str.{ null, 0 };
defer close(tmp_file);
return get_contents(tmp_file);
activeTexture :: proc (texture: GLenum) #foreign "gl" "activeTexture" ---
attachShader :: proc (program: GLProgram, shader: GLShader) -> GLProgram #foreign "gl" "attachShader" ---
-bindAttribLocation :: proc (program: GLProgram, index: GLuint, name: string) #foreign "gl" "bindAttribLocation" ---
+bindAttribLocation :: proc (program: GLProgram, index: GLuint, name: str) #foreign "gl" "bindAttribLocation" ---
bindBuffer :: proc (target: GLenum, buffer: GLBuffer) #foreign "gl" "bindBuffer" ---
bindFramebuffer :: proc (target: GLenum, framebuffer: GLFramebuffer) #foreign "gl" "bindFramebuffer" ---
bindRenderbuffer :: proc (target: GLenum, renderbuffer: GLRenderbuffer) #foreign "gl" "bindRenderbuffer" ---
clearStencil :: proc (s: GLint) #foreign "gl" "clearStencil" ---
colorMask :: proc (red: GLboolean, green: GLboolean, blue: GLboolean, alpha: GLboolean) #foreign "gl" "colorMask" ---
compileShader :: proc (shader: GLShader) #foreign "gl" "compileShader" ---
-compressedTexImage2D :: proc (target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, border: GLint, data: string) #foreign "gl" "compressedTexImage2D" ---
-compressedTexSubImage2D :: proc (target: GLenum, level: GLint, internalformat: GLenum, xoff: GLint, yoff: GLint, width: GLsizei, height: GLsizei, format: GLenum, data: string) #foreign "gl" "compressedTexSubImage2D" ---
+compressedTexImage2D :: proc (target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, border: GLint, data: str) #foreign "gl" "compressedTexImage2D" ---
+compressedTexSubImage2D :: proc (target: GLenum, level: GLint, internalformat: GLenum, xoff: GLint, yoff: GLint, width: GLsizei, height: GLsizei, format: GLenum, data: str) #foreign "gl" "compressedTexSubImage2D" ---
copyBufferSubData :: proc (readTarget: GLenum, writeTarget: GLenum, readOffset: GLintptr, writeOffset: GLintptr, size: GLsizeiptr) #foreign "gl" "copyBufferSubData" ---
copyTexImage2D :: proc (target: GLenum, level: GLint, internalformat: GLenum, x: GLint, y: GLint, width: GLsizei, height: GLsizei, border: GLint) #foreign "gl" "copyTexImage2D" ---
copyTexSubImage2D :: proc (target: GLenum, level: GLint, xoff: GLint, yoff: GLint, x: GLint, y: GLint, width: GLsizei, height: GLsizei) #foreign "gl" "copyTexSubImage2D" ---
getActiveAttrib :: proc (program: GLProgram, index: GLuint, out: ^GLActiveInfo) #foreign "gl" "getActiveAttrib" ---
getActiveUniform :: proc (program: GLProgram, index: GLuint, out: ^GLActiveInfo) #foreign "gl" "getActiveUniform" ---
// getAttachedShaders does not work yet because we can't return a list of things
-getAttribLocation :: proc (program: GLProgram, name: string) -> GLint #foreign "gl" "getAttribLocation" ---
-getBufferSubData :: proc (target: GLenum, srcByteOffset: GLintptr, dstBuffer: string, dstOffset: GLuint, length: GLuint) #foreign "gl" "getBufferSubData" ---
+getAttribLocation :: proc (program: GLProgram, name: str) -> GLint #foreign "gl" "getAttribLocation" ---
+getBufferSubData :: proc (target: GLenum, srcByteOffset: GLintptr, dstBuffer: str, dstOffset: GLuint, length: GLuint) #foreign "gl" "getBufferSubData" ---
// getBufferParameter and getParameter do not work
getError :: proc () -> GLenum #foreign "gl" "getError" ---
getInternalformatParameter :: proc (target: GLenum, internalFormat: GLenum, pname: GLenum) -> GLenum #foreign "gl" "getInternalformatParameter" ---
// many of the 'gets' don't work yet because they return very javascripty things
getProgramParameter :: proc (program: GLProgram, pname: GLenum) -> GLenum #foreign "gl" "getProgramParameter" ---
getShaderParameter :: proc (shader: GLShader, pname: GLenum) -> GLenum #foreign "gl" "getShaderParameter" ---
-getUniformLocation :: proc (program: GLProgram, name: string) -> GLUniformLocation #foreign "gl" "getUniformLocation" ---
+getUniformLocation :: proc (program: GLProgram, name: str) -> GLUniformLocation #foreign "gl" "getUniformLocation" ---
getVertexAttribOffset :: proc (index: GLuint, pname: GLenum) #foreign "gl" "getVertexAttribOffset" ---
hint :: proc (target: GLenum, mode: GLenum) #foreign "gl" "hint" ---
-init :: proc (canvasname: string) -> GLboolean #foreign "gl" "init" ---
-invalidateFramebuffer :: proc (target: GLenum, attachments: string) #foreign "gl" "invalidateFramebuffer" ---
-invalidateSubFramebuffer :: proc (target: GLenum, attachments: string, x: GLint, y: GLint, width: GLsizei, height: GLsizei) #foreign "gl" "invalidateSubFramebuffer" ---
+init :: proc (canvasname: str) -> GLboolean #foreign "gl" "init" ---
+invalidateFramebuffer :: proc (target: GLenum, attachments: str) #foreign "gl" "invalidateFramebuffer" ---
+invalidateSubFramebuffer :: proc (target: GLenum, attachments: str, x: GLint, y: GLint, width: GLsizei, height: GLsizei) #foreign "gl" "invalidateSubFramebuffer" ---
isEnabled :: proc (cap: GLenum) -> GLboolean #foreign "gl" "isEnabled" ---
lineWidth :: proc (width: GLfloat) #foreign "gl" "lineWidth" ---
linkProgram :: proc (program: GLProgram) #foreign "gl" "linkProgram" ---
printProgramInfoLog :: proc (program: GLProgram) #foreign "gl" "printProgramInfoLog" ---
printShaderInfoLog :: proc (shader: GLShader) #foreign "gl" "printShaderInfoLog" ---
readBuffer :: proc (src: GLenum) #foreign "gl" "readBuffer" ---
-readPixels :: proc (x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: string) #foreign "gl" "readPixels" ---
+readPixels :: proc (x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: str) #foreign "gl" "readPixels" ---
renderbufferStorageMultisample :: proc (target: GLenum, samples: GLsizei, internalforamt: GLenum, width: GLsizei, height: GLsizei) #foreign "gl" "renderbufferStorageMultisample" ---
sampleCoverage :: proc (value: GLclampf, invert: GLboolean) #foreign "gl" "sampleCoverage" ---
scissor :: proc (x: GLint, y: GLint, width: GLsizei, height: GLsizei) #foreign "gl" "scissor" ---
-shaderSource :: proc (shader: GLShader, source: string) #foreign "gl" "shaderSource" ---
+shaderSource :: proc (shader: GLShader, source: str) #foreign "gl" "shaderSource" ---
stencilFunc :: proc (func: GLenum, ref: GLint, mask: GLuint) #foreign "gl" "stencilFunc" ---
stencilFuncSeparate :: proc (face: GLenum, func: GLenum, ref: GLint, mask: GLuint) #foreign "gl" "stencilFuncSeparate" ---
stencilMask :: proc (mask: GLuint) #foreign "gl" "stencilMask" ---
stencilMaskSeparate :: proc (face: GLenum, mask: GLenum) #foreign "gl" "stencilMaskSeparate" ---
stencilOp :: proc (fail: GLenum, zfail: GLenum, zpass: GLenum) #foreign "gl" "stencilOp" ---
stencilOpSeparate :: proc (face: GLenum, fail: GLenum, zfail: GLenum, zpass: GLenum) #foreign "gl" "stencilOpSeparate" ---
-texImage2D :: proc (target: GLenum, level: GLint, internalFormat: GLenum, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, type: GLenum, pixels: string) #foreign "gl" "texImage2D" ---
+texImage2D :: proc (target: GLenum, level: GLint, internalFormat: GLenum, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, type: GLenum, pixels: str) #foreign "gl" "texImage2D" ---
texParameterf :: proc (target: GLenum, pname: GLenum, param: GLfloat) #foreign "gl" "texParameterf" ---
texParameteri :: proc (target: GLenum, pname: GLenum, param: GLint) #foreign "gl" "texParameteri" ---
-texSubImage2D :: proc (target: GLenum, level: GLint, xoff: GLint, yoff: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: string) #foreign "gl" "texSubImage2D" ---
+texSubImage2D :: proc (target: GLenum, level: GLint, xoff: GLint, yoff: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: str) #foreign "gl" "texSubImage2D" ---
uniform1f :: proc (loc: GLUniformLocation, x: GLfloat) #foreign "gl" "uniform1f" ---
uniform1i :: proc (loc: GLUniformLocation, x: GLint) #foreign "gl" "uniform1i" ---
uniform2f :: proc (loc: GLUniformLocation, x: GLfloat, y: GLfloat) #foreign "gl" "uniform2f" ---
// of the system package
use package system as system
-#private_file print_buffer : str.StringBuilder;
+#private_file print_buffer : string.StringBuilder;
stdio_init :: proc () {
- print_buffer = str.builder_make(2048);
+ print_buffer = string.builder_make(2048);
}
-print_string :: proc (s: string) {
- str.builder_append(^print_buffer, s);
+print_str :: proc (s: str) {
+ string.builder_append(^print_buffer, s);
if s.data[s.count - 1] == #char "\n" do print_buffer_flush();
}
-print_cstring :: proc (s: cstring) do str.builder_append(^print_buffer, s);
-print_i64 :: proc (n: i64, base: u64 = 10) do str.builder_append(^print_buffer, n, base);
-print_i32 :: proc (n: i32, base: u32 = 10) do str.builder_append(^print_buffer, cast(i64) n, cast(u64) base);
-print_f64 :: proc (n: f64) do str.builder_append(^print_buffer, n);
-print_f32 :: proc (n: f32) do str.builder_append(^print_buffer, cast(f64) n);
-print_bool :: proc (b: bool) do str.builder_append(^print_buffer, b);
-print_ptr :: proc (p: ^void) do str.builder_append(^print_buffer, cast(i64) p, cast(u64) 16);
+print_cstr :: proc (s: cstr) do string.builder_append(^print_buffer, s);
+print_i64 :: proc (n: i64, base: u64 = 10) do string.builder_append(^print_buffer, n, base);
+print_i32 :: proc (n: i32, base: u32 = 10) do string.builder_append(^print_buffer, cast(i64) n, cast(u64) base);
+print_f64 :: proc (n: f64) do string.builder_append(^print_buffer, n);
+print_f32 :: proc (n: f32) do string.builder_append(^print_buffer, cast(f64) n);
+print_bool :: proc (b: bool) do string.builder_append(^print_buffer, b);
+print_ptr :: proc (p: ^void) do string.builder_append(^print_buffer, cast(i64) p, cast(u64) 16);
print_range :: proc (r: range, sep := " ") {
for i: r {
}
print :: proc {
- print_string, print_cstring,
+ print_str, print_cstr,
print_i64, print_i32,
print_f64, print_f32,
print_bool, print_ptr,
print("\n");
}
-printf :: proc (format: string, va: ...) {
+printf :: proc (format: str, va: ...) {
buffer: [2048] u8;
len := 0;
if !vararg_get(va, ^n) do return;
ibuf : [128] u8;
- istr := str.i64_to_string(~~n, 10, Buffer.{ ~~ibuf, 128 });
+ istr := string.i64_to_str(~~n, 10, Buffer.{ ~~ibuf, 128 });
for a: istr {
buffer[len] = a;
if !vararg_get(va, ^n) do return;
ibuf : [128] u8;
- istr := str.i64_to_string(n, 10, Buffer.{ ~~ibuf, 128 });
+ istr := string.i64_to_str(n, 10, Buffer.{ ~~ibuf, 128 });
for a: istr {
buffer[len] = a;
if !vararg_get(va, ^n) do return;
fbuf : [128] u8;
- fstr := str.f64_to_string(~~n, fbuf[0 .. 128]);
+ fstr := string.f64_to_str(~~n, fbuf[0 .. 128]);
for a: fstr {
buffer[len] = a;
if !vararg_get(va, ^n) do return;
fbuf : [128] u8;
- fstr := str.f64_to_string(n, fbuf[0 .. 128]);
+ fstr := string.f64_to_str(n, fbuf[0 .. 128]);
for a: fstr {
buffer[len] = a;
}
case #char "s" {
- str : string;
- if !vararg_get(va, ^str) do return;
+ s : str;
+ if !vararg_get(va, ^s) do return;
- for a: str {
+ for a: s {
buffer[len] = a;
len += 1;
}
if !vararg_get(va, ^n) do return;
ibuf : [128] u8;
- istr := str.i64_to_string(~~n, 16, Buffer.{ ~~ibuf, 128 });
+ istr := string.i64_to_str(~~n, 16, Buffer.{ ~~ibuf, 128 });
for a: istr {
buffer[len] = a;
len += 1;
}
}
+
+ case #char "c" {
+ c : u8;
+ if !vararg_get(va, ^c) do return;
+
+ buffer[len] = c;
+ len += 1;
+ }
}
state = 0;
}
}
- print(string.{ ~~buffer, len });
+ print(str.{ ~~buffer, len });
}
// This works on both slices and arrays
if print_buffer.len == 0 do return;
^print_buffer
- |> str.builder_to_string()
- |> system.output_string();
+ |> string.builder_to_str()
+ |> system.output_str();
- ^print_buffer |> str.builder_clear();
+ ^print_buffer |> string.builder_clear();
}
-package core.str
+package core.string
-make :: proc (s: cstring) -> string {
+make :: proc (s: cstr) -> str {
len :: length(s);
- return string.{ count = len, data = s };
+ return str.{ count = len, data = s };
}
length :: proc {
- proc (s: cstring) -> u32 {
+ proc (s: cstr) -> u32 {
len := 0;
c := s;
while *c != #char "\0" {
return len;
},
- proc (s: string) -> u32 {
+ proc (s: str) -> u32 {
return s.count;
},
}
-alloc_copy :: proc (orig: string) -> string {
- new_str : string;
+alloc_copy :: proc (orig: str) -> str {
+ new_str : str;
new_str.data = calloc(sizeof u8 * orig.count);
new_str.count = orig.count;
copy(orig, new_str);
return new_str;
}
-copy :: proc (orig: string, dest: string) {
+copy :: proc (orig: str, dest: str) {
len := orig.count;
if dest.count < len do len = dest.count;
for i: 0 .. len do dest.data[i] = orig.data[i];
}
-concat :: proc (s1: string, s2: string) -> string {
+concat :: proc (s1: str, s2: str) -> str {
len1 :: length(s1);
len2 :: length(s2);
for i: 0 .. len1 do data[i] = s1[i];
for i: 0 .. len2 do data[i + len1] = s2[i];
- return string.{ data, len1 + len2 };
+ return str.{ data, len1 + len2 };
}
-free :: proc (s: string) do cfree(s.data);
+free :: proc (s: str) do cfree(s.data);
-// This is an example doc string
+// This is an example doc str
// You can have as many comments as you want
// It documents the split function
-split :: proc (str: string, delim: u8) -> []string {
+split :: proc (s: str, delim: u8) -> []str {
delim_count := 0;
- for i: 0 .. str.count do if str[i] == delim do delim_count += 1;
+ for i: 0 .. s.count do if s[i] == delim do delim_count += 1;
- strarr := cast(^string) calloc(sizeof string * (delim_count + 1));
+ strarr := cast(^str) calloc(sizeof str * (delim_count + 1));
curr_str := 0;
begin := 0;
- for i: 0 .. str.count {
- if str[i] == delim {
- strarr[curr_str] = str.data[begin .. i];
+ for i: 0 .. s.count {
+ if s[i] == delim {
+ strarr[curr_str] = s.data[begin .. i];
begin = i + 1;
curr_str += 1;
}
}
- strarr[curr_str] = str.data[begin .. str.count];
+ strarr[curr_str] = s.data[begin .. s.count];
return strarr[0 .. delim_count + 1];
}
-substr :: proc (str: string, sub: string) -> string {
- for i: 0 .. str.count {
- while j := 0; j < sub.count && str[i + j] == sub[j] {
- j += 1;
-
- if j == sub.count do return str.data[i .. i + j];
- }
- }
-
- return str.data[0 .. 0];
-}
+// substr :: proc (s: str, sub: str) -> str {
+// for i: 0 .. str.count {
+// while j := 0; j < sub.count && str[i + j] == sub[j] {
+// j += 1;
+//
+// if j == sub.count do return str.data[i .. i + j];
+// }
+// }
+//
+// return str.data[0 .. 0];
+// }
-contains :: proc (str: string, c: u8) -> bool {
- for ch: str do if ch == c do return true;
+contains :: proc (s: str, c: u8) -> bool {
+ for ch: s do if ch == c do return true;
return false;
}
-// compare :: proc (str1: string, str2: string) -> i32 {
+// compare :: proc (str1: str, str2: str) -> i32 {
// if str1.count != str2.count do return str1.count - str2.count;
//
// i := 0;
// return ~~(str1[i] - str2[i]);
// }
-equal :: proc (str1: string, str2: string) -> bool {
+equal :: proc (str1: str, str2: str) -> bool {
if str1.count != str2.count do return false;
while i := 0; i < str1.count {
if str1[i] != str2[i] do return false;
return true;
}
-starts_with :: proc (str1: string, str2: string) -> bool {
+starts_with :: proc (str1: str, str2: str) -> bool {
if str1.count < str2.count do return false;
while i := 0; i < str2.count {
if str1[i] != str2[i] do return false;
return true;
}
-strip_leading_whitespace :: proc (str: ^string) {
- while true do switch str.data[0] {
+strip_leading_whitespace :: proc (s: ^str) {
+ while true do switch s.data[0] {
case #char " ", #char "\t", #char "\n", #char "\r" {
- str.data += 1;
- str.count -= 1;
+ s.data += 1;
+ s.count -= 1;
}
case #default do return;
}
}
-strip_trailing_whitespace :: proc (str: ^string) {
- while true do switch str.data[str.count - 1] {
+strip_trailing_whitespace :: proc (s: ^str) {
+ while true do switch s.data[s.count - 1] {
case #char " ", #char "\t", #char "\n", #char "\r" {
- str.count -= 1;
+ s.count -= 1;
}
case #default do return;
};
}
-builder_add_string :: proc (use sb: ^StringBuilder, str: string) -> ^StringBuilder {
- len_total :: len + str.count;
+builder_add_str :: proc (use sb: ^StringBuilder, s: str) -> ^StringBuilder {
+ len_total :: len + s.count;
if cap >= len_total {
- for i: 0 .. str.count do data[len + i] = str[i];
- len += str.count;
+ for i: 0 .. s.count do data[len + i] = s[i];
+ len += s.count;
return sb;
}
data = new_data;
cap = new_cap;
- for i: 0 .. str.count do data[len + i] = str[i];
- len += str.count;
+ for i: 0 .. s.count do data[len + i] = s[i];
+ len += s.count;
return sb;
}
-builder_add_cstring :: proc (use sb: ^StringBuilder, cstr: cstring) -> ^StringBuilder {
- s := make(cstr);
- return builder_add_string(sb, s);
+builder_add_cstr :: proc (use sb: ^StringBuilder, cstring: cstr) -> ^StringBuilder {
+ s := make(cstring);
+ return builder_add_str(sb, s);
}
-i64_to_string :: proc (n_: i64, base: u64, buf: Buffer) -> string {
+i64_to_str :: proc (n_: i64, base: u64, buf: Buffer) -> str {
n := cast(u64) n_;
is_neg := false;
c -= 1;
}
- return string.{ data = c + 1, count = len };
+ return str.{ data = c + 1, count = len };
}
// NOTE: This is a big hack but it will work for now
-f64_to_string :: proc (f: f64, buf: [] u8) -> string {
+f64_to_str :: proc (f: f64, buf: [] u8) -> str {
a := f;
a *= 10000.0;
v := cast(i64) a;
b := Buffer.{ cast(^void) buf.data, buf.count };
len := 0;
- s1 := i64_to_string(v / 10000, 10, b);
+ s1 := i64_to_str(v / 10000, 10, b);
for i: 0 .. s1.count do buf.data[i] = s1.data[i];
buf.data[s1.count] = #char ".";
len = s1.count + 1;
if v < ~~0 do v = -v;
- s2 := i64_to_string(v % 10000, 10, b);
+ s2 := i64_to_str(v % 10000, 10, b);
for i: 0 .. s2.count do buf.data[s1.count + 1 + i] = s2.data[i];
len += s2.count;
- return string.{ buf.data, len };
+ return str.{ buf.data, len };
}
builder_add_i64 :: proc (use sb: ^StringBuilder, n: i64, base: u64 = 10) -> ^StringBuilder {
buf : [256] u8;
- s := i64_to_string(n, base, Buffer.{ cast(^void) buf, 256 });
- return builder_add_string(sb, s);
+ s := i64_to_str(n, base, Buffer.{ cast(^void) buf, 256 });
+ return builder_add_str(sb, s);
}
builder_add_f64 :: proc (use sb: ^StringBuilder, f: f64) -> ^StringBuilder {
buf : [256] u8;
- s := f64_to_string(f, buf[0 .. 256]);
- return builder_add_string(sb, s);
+ s := f64_to_str(f, buf[0 .. 256]);
+ return builder_add_str(sb, s);
}
builder_add_bool :: proc (use sb: ^StringBuilder, b: bool) -> ^StringBuilder {
if b {
- return builder_add_string(sb, "true");
+ return builder_add_str(sb, "true");
} else {
- return builder_add_string(sb, "false");
+ return builder_add_str(sb, "false");
}
return null;
}
builder_append :: proc {
- builder_add_string,
- builder_add_cstring,
+ builder_add_str,
+ builder_add_cstr,
builder_add_i64,
builder_add_f64,
builder_add_bool,
}
-builder_to_string :: proc (use sb: ^StringBuilder) -> string {
- return string.{ data, len };
+builder_to_str :: proc (use sb: ^StringBuilder) -> str {
+ return str.{ data, len };
}
builder_clear :: proc (use sb: ^StringBuilder) -> ^StringBuilder {
return sb;
}
-read_u32 :: proc (str: ^string, out: ^u32) {
+read_u32 :: proc (s: ^str, out: ^u32) {
n := 0;
- strip_leading_whitespace(str);
- while str.data[0] >= #char "0" && str.data[0] <= #char "9" {
+ strip_leading_whitespace(s);
+ while s.data[0] >= #char "0" && s.data[0] <= #char "9" {
n *= 10;
- n += cast(u32) (str.data[0] - #char "0");
+ n += cast(u32) (s.data[0] - #char "0");
- str.data += 1;
- str.count -= 1;
+ s.data += 1;
+ s.count -= 1;
}
*out = n;
}
-read_char :: proc (str: ^string, out: ^u8) {
- *out = str.data[0];
- str.data += 1;
- str.count -= 1;
+read_char :: proc (s: ^str, out: ^u8) {
+ *out = s.data[0];
+ s.data += 1;
+ s.count -= 1;
}
-read_chars :: proc (str: ^string, out: ^string, char_count := 1) {
- out.data = str.data;
+read_chars :: proc (s: ^str, out: ^str, char_count := 1) {
+ out.data = s.data;
out.count = char_count;
- str.data += char_count;
- str.count -= char_count;
+ s.data += char_count;
+ s.count -= char_count;
}
-discard_chars :: proc (str: ^string, char_count := 1) {
- str.data += char_count;
- str.count -= char_count;
+discard_chars :: proc (s: ^str, char_count := 1) {
+ s.data += char_count;
+ s.count -= char_count;
}
// Goes up to but not including the closest newline or EOF
-read_line :: proc (str: ^string, out: ^string) {
- out.data = str.data;
+read_line :: proc (s: ^str, out: ^str) {
+ out.data = s.data;
out.count = 0;
- for ch: *str {
+ for ch: *s {
if ch == #char "\n" do break;
out.count += 1;
}
- str.data += out.count;
- str.count -= out.count;
+ s.data += out.count;
+ s.count -= out.count;
- if str.count > 0 {
- str.data += 1;
- str.count -= 1;
+ if s.count > 0 {
+ s.data += 1;
+ s.count -= 1;
}
}
-read_until :: proc (str: ^string, upto: u8, skip := 0) -> string {
- if str.count == 0 do return "";
+read_until :: proc (s: ^str, upto: u8, skip := 0) -> str {
+ if s.count == 0 do return "";
- out : string;
- out.data = str.data;
+ out : str;
+ out.data = s.data;
out.count = 0;
- s := skip;
- for ch: *str {
+ rem := skip;
+ for ch: *s {
if ch == upto {
- if s <= 0 do break;
- else do s -= 1;
+ if rem <= 0 do break;
+ else do rem -= 1;
}
out.count += 1;
}
- str.data += out.count;
- str.count -= out.count;
+ s.data += out.count;
+ s.count -= out.count;
return out;
}
-read_until_either :: proc (str: ^string, skip: u32, uptos: ..u8) -> string {
- if str.count == 0 do return "";
+read_until_either :: proc (s: ^str, skip: u32, uptos: ..u8) -> str {
+ if s.count == 0 do return "";
- out : string;
- out.data = str.data;
+ out : str;
+ out.data = s.data;
out.count = 0;
- s := skip;
- for ch: *str {
+ rem := skip;
+ for ch: *s {
for upto: uptos {
if ch == upto {
- if s <= 0 do break break;
- else do s -= 1;
+ if rem <= 0 do break break;
+ else do rem -= 1;
}
}
out.count += 1;
}
- str.data += out.count;
- str.count -= out.count;
+ s.data += out.count;
+ s.count -= out.count;
return out;
}
-advance_line :: proc (str: ^string) {
- if str.count == 0 do return;
+advance_line :: proc (s: ^str) {
+ if s.count == 0 do return;
adv := 0;
- while str.data[adv] != #char "\n" do adv += 1;
+ while s.data[adv] != #char "\n" do adv += 1;
- str.data += adv + 1;
- str.count -= adv + 1;
+ s.data += adv + 1;
+ s.count -= adv + 1;
}
read :: proc {
-package core.str.reader
+package core.string.reader
+
+use package core { printf }
StringReader :: struct {
data : ^u8;
count : u32;
// The original string.
- original_str : string;
+ original_str : str;
}
-make :: proc (str: string) -> StringReader {
+make :: proc (s: str) -> StringReader {
reader : StringReader;
- init(^reader, str);
+ init(^reader, s);
return reader;
}
-init :: proc (use reader: ^StringReader, str: string) {
- original_str = str;
+init :: proc (use reader: ^StringReader, orig_str: str) {
+ original_str = orig_str;
data = original_str.data;
count = original_str.count;
}
return data[0];
}
-read_bytes :: proc (use reader: ^StringReader, byte_count := 1) -> string {
+read_bytes :: proc (use reader: ^StringReader, byte_count := 1) -> str {
bc := byte_count;
if count < bc do bc = count;
count -= bc;
}
- return string.{ data, bc };
+ return str.{ data, bc };
}
-read_line :: proc (use reader: ^StringReader) -> string {
- out : string;
+read_line :: proc (use reader: ^StringReader) -> str {
+ out : str;
out.data = data;
out.count = 0;
// HACK(Brendan): I want to use a for loop, but I don't know why.
- for ch: *(cast(^string) reader) {
+ for ch: *(cast(^str) reader) {
if ch == #char "\n" do break;
out.count += 1;
}
return out;
}
-read_until :: proc (use reader: ^StringReader, skip: u32, uptos: ..u8) -> string {
- if count == 0 do return string.{ null, 0 };
+read_until :: proc (use reader: ^StringReader, skip: u32, uptos: ..u8) -> str {
+ if count == 0 do return str.{ null, 0 };
- out : string;
+ out : str;
out.data = data;
out.count = 0;
s := skip;
// HACK(Brendan): See above.
- for ch: *(cast(^string) reader) {
+ for ch: *(cast(^str) reader) {
for upto: uptos do if ch == upto {
- if s <= 0 do break;
+ if s == 0 do break break;
else do s -= 1;
+
+ break;
}
out.count += 1;
skip_whitespace :: proc (use reader: ^StringReader) {
- while count > 0 do switch *data {
+ while count > 0 do switch data[0] {
case #char " ", #char "\t", #char "\n", #char "\r" {
data += 1;
count -= 1;
data += bc;
count -= bc;
}
+
+
+
+starts_with :: proc (use reader: ^StringReader, s: str) -> bool {
+ if count < s.count do return false;
+ while i := 0; i < s.count {
+ if data[i] != s[i] do return false;
+ i += 1;
+ }
+ return true;
+}
package core.strmap
use package core.array as array
-use package core.str as str
+use package core.string as string
use package core { print }
StrMap :: struct ($T) {
StrMapEntry :: struct ($T) {
next : i32;
- key : string;
+ key : str;
value : T;
}
array.free(^key_store);
}
-put :: proc (use smap: ^StrMap($T), key: string, value: T, copy_key := false) {
+put :: proc (use smap: ^StrMap($T), key: str, value: T, copy_key := false) {
lr := lookup(smap, key);
if lr.entry_index >= 0 {
// array.ensure_capacity(^key_store, key_store.count + key.count);
// key_store.count += key.count;
- // str.copy(key, new_key);
+ // string.copy(key, new_key);
// }
entry : StrMapEntry(T);
hashes[lr.hash_index] = entries.count - 1;
}
-has :: proc (use smap: ^StrMap($T), key: string) -> bool {
+has :: proc (use smap: ^StrMap($T), key: str) -> bool {
lr := lookup(smap, key);
return lr.entry_index >= 0;
}
-get :: proc (use smap: ^StrMap($T), key: string, default := cast(T) 0) -> T {
+get :: proc (use smap: ^StrMap($T), key: str, default := cast(T) 0) -> T {
lr := lookup(smap, key);
if lr.entry_index >= 0 do return entries[lr.entry_index].value;
return default;
}
-delete :: proc (use smap: ^StrMap($T), key: string) {
+delete :: proc (use smap: ^StrMap($T), key: str) {
lr := lookup(smap, key);
if lr.entry_index < 0 do return;
}
#private_file
-lookup :: proc (use smap: ^StrMap($T), key: string) -> StrMapLookupResult {
+lookup :: proc (use smap: ^StrMap($T), key: str) -> StrMapLookupResult {
lr := StrMapLookupResult.{};
hash: u32 = 5381;
lr.entry_index = hashes[lr.hash_index];
while lr.entry_index >= 0 {
- if str.equal(entries[lr.entry_index].key, key) do return lr;
+ if string.equal(entries[lr.entry_index].key, key) do return lr;
lr.entry_prev = lr.entry_index;
lr.entry_index = entries[lr.entry_index].next;
use package core
use package main as main
-output_string :: proc (s: string) -> u32 #foreign "host" "print_str" ---
+output_str :: proc (s: str) -> u32 #foreign "host" "print_str" ---
// The builtin _start proc.
// Sets up everything needed for execution.
context.allocator = allocator.heap_allocator;
context.temp_allocator = allocator.heap_allocator;
- args : [] cstring;
+ args : [] cstr;
args.data = null;
args.count = 0;
STDOUT_FILENO :: 1
-output_string :: proc (s: string) -> u32 {
+output_str :: proc (s: str) -> u32 {
vec := IOVec.{ buf = s.data, len = s.count };
tmp : Size;
fd_write(STDOUT_FILENO, IOVecArray.{ ^vec, 1 }, ^tmp);
args_sizes_get(^argc, ^argv_buf_size);
- argv := cast(^cstring) calloc(sizeof cstring * argc);
- argv_buf := cast(cstring) calloc(argv_buf_size);
+ argv := cast(^cstr) calloc(sizeof cstr * argc);
+ argv_buf := cast(cstr) calloc(argv_buf_size);
args_get(argv, argv_buf);
fd_filestat_set_times :: proc (fd: FileDescriptor, atim: Timestamp, mtim: Timestamp, fst_flags: FSTFlags) -> Errno #foreign "wasi_unstable" "fd_filestat_set_times" ---
fd_pread :: proc (fd: FileDescriptor, iovs: IOVecArray, offset: Filesize, nread: ^Size) -> Errno #foreign "wasi_unstable" "fd_pread" ---
fd_prestat_get :: proc (fd: FileDescriptor, buf: ^PrestatTagged) -> Errno #foreign "wasi_unstable" "fd_prestat_get" ---
-fd_prestat_dir_name :: proc (fd: FileDescriptor, path: string) -> Errno #foreign "wasi_unstable" "fd_prestat_dir_name" ---
+fd_prestat_dir_name :: proc (fd: FileDescriptor, path: str) -> Errno #foreign "wasi_unstable" "fd_prestat_dir_name" ---
fd_pwrite :: proc (fd: FileDescriptor, iovs: IOVecArray, offset: Filesize, nwritten: ^Size) -> Errno #foreign "wasi_unstable" "fd_pwrite" ---
fd_read :: proc (fd: FileDescriptor, iovs: IOVecArray, nread: ^Size) -> Errno #foreign "wasi_unstable" "fd_read" ---
fd_readdir :: proc (fd: FileDescriptor, buf: ^u8, buf_len: Size, cookie: DirCookie, bufused: ^Size) -> Errno #foreign "wasi_unstable" "fd_readdir" ---
fd_tell :: proc (fd: FileDescriptor, offset: ^Filesize) -> Errno #foreign "wasi_unstable" "fd_tell" ---
fd_write :: proc (fd: FileDescriptor, iovs: IOVecArray, nwritten: ^Size) -> Errno #foreign "wasi_unstable" "fd_write" ---
-path_create_directory :: proc (fd: FileDescriptor, path: string) -> Errno #foreign "wasi_unstable" "path_create_directory" ---
-path_filestat_get :: proc (fd: FileDescriptor, flags: LookupFlags, path: string, buf: ^FileStat) -> Errno #foreign "wasi_unstable" "path_filestat_get" ---
-path_filestat_set_times :: proc (fd: FileDescriptor, flags: LookupFlags, path: string, atim: Timestamp, mtim: Timestamp, fst_flags: FSTFlags) -> Errno #foreign "wasi_unstable" "path_filestat_set_times" ---
+path_create_directory :: proc (fd: FileDescriptor, path: str) -> Errno #foreign "wasi_unstable" "path_create_directory" ---
+path_filestat_get :: proc (fd: FileDescriptor, flags: LookupFlags, path: str, buf: ^FileStat) -> Errno #foreign "wasi_unstable" "path_filestat_get" ---
+path_filestat_set_times :: proc (fd: FileDescriptor, flags: LookupFlags, path: str, atim: Timestamp, mtim: Timestamp, fst_flags: FSTFlags) -> Errno #foreign "wasi_unstable" "path_filestat_set_times" ---
-path_link :: proc (fd: FileDescriptor, old_flags: LookupFlags, old_path: string, new_fd: FileDescriptor, new_path: string) -> Errno #foreign "wasi_unstable" "path_link" ---
+path_link :: proc (fd: FileDescriptor, old_flags: LookupFlags, old_path: str, new_fd: FileDescriptor, new_path: str) -> Errno #foreign "wasi_unstable" "path_link" ---
path_open :: proc
( fd: FileDescriptor
, dirflags: LookupFlags
- , path: string
+ , path: str
, oflags: OFlags
, fs_rights_base: Rights
, fs_rights_inherting: Rights
) -> Errno
#foreign "wasi_unstable" "path_open" ---
-path_readlink :: proc (fd: FileDescriptor, path: string, buf: ^u8, buf_len: Size, bufused: ^Size) -> Errno #foreign "wasi_unstable" "path_readlink" ---
-path_remove_directory :: proc (fd: FileDescriptor, path: string) -> Errno #foreign "wasi_unstable" "path_remove_directory" ---
-path_rename :: proc (fd: FileDescriptor, old_path: string, new_fd: FileDescriptor, new_path: string) -> Errno #foreign "wasi_unstable" "path_rename" ---
-path_symlink :: proc (old_path: ^u8, old_path_len: Size, fd: FileDescriptor, new_path: string) -> Errno #foreign "wasi_unstable" "path_symlink" ---
-path_unlink_file :: proc (fd: FileDescriptor, path: string) -> Errno #foreign "wasi_unstable" "path_unlink_file" ---
+path_readlink :: proc (fd: FileDescriptor, path: str, buf: ^u8, buf_len: Size, bufused: ^Size) -> Errno #foreign "wasi_unstable" "path_readlink" ---
+path_remove_directory :: proc (fd: FileDescriptor, path: str) -> Errno #foreign "wasi_unstable" "path_remove_directory" ---
+path_rename :: proc (fd: FileDescriptor, old_path: str, new_fd: FileDescriptor, new_path: str) -> Errno #foreign "wasi_unstable" "path_rename" ---
+path_symlink :: proc (old_path: ^u8, old_path_len: Size, fd: FileDescriptor, new_path: str) -> Errno #foreign "wasi_unstable" "path_symlink" ---
+path_unlink_file :: proc (fd: FileDescriptor, path: str) -> Errno #foreign "wasi_unstable" "path_unlink_file" ---
poll_oneoff :: proc (in: ^Subscription, out: ^Event, nsubscriptions: Size, nevents: ^Size) -> Errno #foreign "wasi_unstable" "poll_oneoff" ---
The following should work when this is patched:
var := some.packages.nested.here.StructName.{ value1, value2, ... };
-
- [ ] Rearrange APIs. There is a lot of functionality in the standard libraries,
- but it isn't organized in a usable way.
- - 'core.array' contains a lot of functionality that would also apply to
- slices. 'core.slice' should contain this functionality and 'core.array'
- can provide wrappers that convert the array to a slice.
- - 'core.str' is a bad name, it should be 'core.string'. The issue is that
- it conflicts with 'builtin.string'. These two should be switched. Type
- name should be 'str' and package name should be 'string'
+ [ ] 'use' statements have two different variations and should be unified.
+ They can be used to include a package, 'use package', and they can
+ be used to add names from a namespace to the current scope. The problem
+ is that 'use package' can only be at the top level, and 'use' can only
+ be used at the block level.
+
[ ] :: should not declare a local variable, just bind a name to an expression.
They can still be lexically scoped.
There are many differeny places where the standard API for WASI and JS
backends could be improved. Here are some of the target areas.
+ [ ] Rearrange APIs. There is a lot of functionality in the standard libraries,
+ but it isn't organized in a usable way.
+ - 'core.array' contains a lot of functionality that would also apply to
+ slices. 'core.slice' should contain this functionality and 'core.array'
+ can provide wrappers that convert the array to a slice.
+ - 'core.str' is a bad name, it should be 'core.string'. The issue is that
+ it conflicts with 'builtin.string'. These two should be switched. Type
+ name should be 'str' and package name should be 'string'
+
[ ] Expand capabilities of file api on WASI.
[ ] Add clock / time api for both backends
[ ] Better random number api
- match: '\b(package|struct|proc|use|global|enum|if|elseif|else|for|while|do|break|continue|fallthrough|return|as|cast|sizeof|alignof|defer|switch|case)\b'
scope: keyword.control.onyx
- - match: '\b(bool|void|i8|u8|i16|u16|i32|u32|i64|u64|f32|f64|rawptr|string|cstring|range)\b'
+ - match: '\b(bool|void|i8|u8|i16|u16|i32|u32|i64|u64|f32|f64|rawptr|str|cstr|range)\b'
scope: storage.type
- match: '\b(i8x16|i16x8|i32x4|i64x2|f32x4|f64x2|v128)\b'
syn keyword onyxType f32
syn keyword onyxType f64
syn keyword onyxType rawptr
+syn keyword onyxType str cstr
syn keyword onyxType i8x16 i16x8 i32x4 i64x2 f32x4 f64x2 v128
syn keyword onyxConstant true false null
dirent := cast(^DirEnt) buf;
while true {
- print(string.{ cast(^u8) (cast(u32) dirent + sizeof DirEnt), dirent.d_namlen });
+ print(str.{ cast(^u8) (cast(u32) dirent + sizeof DirEnt), dirent.d_namlen });
print("\n");
print("\td_namlen: ");
Package* p = program_info_package_lookup_or_create(prog, "builtin", prog->global_scope, a);
- builtin_string_type = (AstType *) symbol_raw_resolve(p->scope, "string");
+ builtin_string_type = (AstType *) symbol_raw_resolve(p->scope, "str");
if (builtin_string_type == NULL) {
- onyx_report_error((OnyxFilePos) { 0 }, "'string' struct not found in builtin package.");
+ onyx_report_error((OnyxFilePos) { 0 }, "'str' struct not found in builtin package.");
return;
}
AstStructMember *member = s_node->members[i];
member->type_node = symres_type(member->type_node);
+ if (!node_is_type(member->type_node)) {
+ onyx_report_error(member->token->pos, "Member type is not a type.");
+ return type;
+ }
+
if (member->flags & Ast_Flag_Struct_Mem_Used) {
AstStructType *used = (AstStructType *) member->type_node;
}
func->return_type = symres_type(func->return_type);
+ if (!node_is_type((AstNode *) func->return_type)) {
+ onyx_report_error(func->token->pos, "Return type is not a type.");
+ }
scope_enter(func->scope);
u32 return_align = type_alignment_of(return_type);
bh_align(return_size, return_align);
- if (cc == CC_Return_Stack)
+ if (cc == CC_Return_Stack) {
+ bh_align(stack_grow_amm, return_align);
stack_grow_amm += return_size;
+ }
+
+ bh_align(stack_grow_amm, 16);
if (needs_stack) {
WID(WI_GLOBAL_GET, stack_top_idx);
}
}
-vararg_test :: proc (prefix: string, nums: ..i32) {
+vararg_test :: proc (prefix: str, nums: ..i32) {
print(prefix);
for num: nums {
print(num);
return ni;
}
-print_strings :: proc (ss: ..string) {
- for s: ss do print_string(s);
+print_strings :: proc (ss: ..str) {
+ for s: ss do print_str(s);
}
multi_max :: proc (nums: ..$T) -> T {
return s;
}
-main :: proc (args: [] cstring) {
+main :: proc (args: [] cstr) {
switch_demo();
print_strings("This ", "is ", "a ", "test.\n");
use package core
-main :: proc (args: [] cstring) {
+main :: proc (args: [] cstr) {
println("Hello, World!");
}
use package core
-main :: proc (args: [] cstring) {
- imap : i32map.I32Map(string);
+main :: proc (args: [] cstr) {
+ imap : i32map.I32Map(str);
i32map.init(^imap);
defer {
print("Freeing map\n");
use package core;
-old_va_test :: proc (prefix: string, va: ..i32) {
+old_va_test :: proc (prefix: str, va: ..i32) {
println(prefix);
for v: va do println(v);
}
-new_va_test :: proc (prefix: string, va: ...) {
+new_va_test :: proc (prefix: str, va: ...) {
println(prefix);
for i: 0 .. va.count {
}
}
-main :: proc (args: [] cstring) {
+main :: proc (args: [] cstr) {
new_va_test("foo", 1, 2, 3.0f, 5.0f);
old_va_test("bar", 1);