added more robustness to builder and array api
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 16 Dec 2020 18:17:27 +0000 (12:17 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 16 Dec 2020 18:17:27 +0000 (12:17 -0600)
core/array.onyx
core/string/builder.onyx
core/string/reader.onyx
onyx
progs/odin_example.onyx
src/onyxparser.c

index b367d3a50cf9c463011c508db5c51d5c71c1671c..18c6f0f84ef4fda4fc9424f9169e9023e2c865ba 100644 (file)
@@ -21,21 +21,25 @@ clear :: proc (arr: ^[..] $T) {
     arr.count = 0;
 }
 
-ensure_capacity :: proc (arr: ^[..] $T, cap: u32) {
-    if arr.capacity >= cap do return;
+ensure_capacity :: proc (arr: ^[..] $T, cap: u32) -> bool {
+    if arr.capacity >= cap do return true;
 
     while cap > arr.capacity do arr.capacity <<= 1;
-    arr.data = cresize(arr.data, sizeof T * arr.capacity);
+    new_data := cresize(arr.data, sizeof T * arr.capacity);
+    if new_data == null do return false;
+    arr.data = new_data;
+    return true;
 }
 
-push :: proc (arr: ^[..] $T, x: T) {
-    ensure_capacity(arr, arr.count + 1);
+push :: proc (arr: ^[..] $T, x: T) -> bool {
+    if !ensure_capacity(arr, arr.count + 1) do return false;
     arr.data[arr.count] = x;
     arr.count += 1;
+    return true;
 }
 
-insert :: proc (arr: ^[..] $T, idx: u32, x: T) {
-    ensure_capacity(arr, arr.count + 1);
+insert :: proc (arr: ^[..] $T, idx: u32, x: T) -> bool {
+    if !ensure_capacity(arr, arr.count + 1) do return false;
 
     arr.count += 1;
     while i := arr.count; i > idx {
@@ -44,6 +48,7 @@ insert :: proc (arr: ^[..] $T, idx: u32, x: T) {
     }
 
     arr.data[idx] = x;
+    return true;
 }
 
 remove :: proc (arr: ^[..] $T, elem: T) {
index 37372e1afc50e40c8fb9bdf339e45b989606692a..69ee4d5a8e33f07b8b508eeea2af02a12e1a1ae0 100644 (file)
@@ -31,7 +31,7 @@ add_str :: proc (use sb: ^Builder, s: str) -> ^Builder {
 
     if data.capacity < len_total do #context_scope {
         context.allocator = alloc;
-        array.ensure_capacity(^data, len_total);
+        if !array.ensure_capacity(^data, len_total) do return sb;
     }
 
     for i: 0 .. s.count do data[data.count + i] = s[i];
index f1dcaa781df381f52186950762f4be602f18f34c..b7bc8a7e2dbbc0d1d3b0bfd481809e4bbb89c4b1 100644 (file)
@@ -157,7 +157,7 @@ advance_line :: proc (use reader: ^StringReader) {
     if count == 0 do return;
 
     adv := 0;
-    while data[adv] != #char "\n" do adv += 1;
+    while data[adv] != #char "\n" && adv <= count - 1 do adv += 1;
 
     data += adv + 1;
     count -= adv + 1;
diff --git a/onyx b/onyx
index 51cdf8eabc92d9d7b774e792c1a5c4ca754ed783..9703240b979e6b851e26f5f62093db6e93fc2d0c 100755 (executable)
Binary files a/onyx and b/onyx differ
index e3dea71433c0b014c66bf53d8024afa71435273f..dcf5583a3c694fd596ff1007c0d2a23c2ffb94f9 100644 (file)
@@ -91,9 +91,5 @@ main :: proc (args: [] cstr) {
         }
     }
 
-    print("The program \"");
-    print(program);
-    print("\" calculates the value ");
-    print(accumulator);
-    print("\n");
+    printf("The program \"%s\" calculates the value %i\n", program, accumulator);
 }
index dd76093de5dd93d80717823bcfe2810a875ea3dd..47052f15a0861f01a9b19704919bc77f5851893c 100644 (file)
@@ -1251,15 +1251,18 @@ static AstNode* parse_statement(OnyxParser* parser) {
                 assignment->right = builtin_context_variable;
                 context_tmp->next = (AstNode *) assignment;
 
-                AstBlock* context_block = parse_block(parser);
-                needs_semicolon = 0;
-                assignment->next = (AstNode *) context_block;
-
                 AstBinaryOp* assignment2 = make_node(AstBinaryOp, Ast_Kind_Binary_Op);
                 assignment2->operation = Binary_Op_Assign;
                 assignment2->left = builtin_context_variable;
                 assignment2->right = (AstTyped *) context_tmp;
-                context_block->next = (AstNode *) assignment2;
+
+                AstDefer* defer_node = make_node(AstDefer, Ast_Kind_Defer);
+                defer_node->stmt = (AstNode *) assignment2;
+                assignment->next = (AstNode *) defer_node;
+
+                AstBlock* context_block = parse_block(parser);
+                needs_semicolon = 0;
+                defer_node->next = (AstNode *) context_block;
 
                 retval = (AstNode *) context_tmp;
                 break;