Commit Graph

32 Commits

Author SHA1 Message Date
guberathome
0c038365d7
IO.Raw (#1243)
* feat!: move C library wrapper funtions to IO.Raw

* docs: fixed doc string for (String.allocated?)

* docs: removed superfluous parameter names for defns

* fix: replaces IO.exit by System.exit

* fix: ./test/regression.carp for (IO.read->EOF)

* fix: ./test/system.carp

* feat: implemented IO.fwrite!

* feat!: removed IO.exit

* feat!: raw character input now returns Int instead of Char

* fix: removed irritating space chars

* fix: repaired ./example/carp_demo.carp

* fix: reverted System.exit to return an Int for SDL examples

* fix: removed System.exit!

Co-authored-by: guberatsie <gunnar.bernhardt@siemens.com>
2021-06-17 17:33:10 +02:00
guberathome
6cd2a96486
clean up IO library (#1232) 2021-06-08 21:05:51 +02:00
Veit Heller
e05d55150d
fix: correct the type of carp-init-globals (#1169)
Co-authored-by: Tim Dévé <timdeve@users.noreply.github.com>

Co-authored-by: Tim Dévé <timdeve@users.noreply.github.com>
2021-02-04 08:40:53 +01:00
Scott Olsen
892a972660
Pointer: Add utility functions (#1012)
* Pointer: Add utility functions

This commit adds a few more utility functions to `Pointer.carp`.

- Pointer.set-unsafe: Sets the value of a pointer to some arbitrary Carp
  value, without type checking. Users need to ensure this operation is
  safe.
- Pointer.set: Sets the value of a pointer to a value of type t to a
  value that has the same type.
- Pointer.cast: Casts a pointer to a value of type t to a pointer to a
  value of type `a`--the argument passed is ignored, it is only used to
  determine the type to cast to.
- Pointer.leak: Copies a Carp reference to a new pointer to the same
  value. This creates a leak since Carp will not automatically clean up
  this memory.
- Pointer.free: Frees a pointer p. Users need to ensure calls to this
  function are safe and do not produce errors like a double free.
  Intended for use with leak.

Here's an example of some of these functions in action:

```
(defn foo []
  (let-do [p (Pointer.leak "leaky")] ;; create a new pointer
    (ignore (Pointer.set p @"foo")) ;; set the pointer to "foo"
    (println* (Pointer.to-value p)) ;; convert to a Carp val to print
    (Pointer.free p) ;; finally, free it.
    0))
(foo)
=> Compiled to 'out/Untitled' (executable)
foo
0
```

And the C of interest:

```
int foo() {
    int _35;
    /* let */ {
        static String _6 = "leaky";
        String *_6_ref = &_6;
        String* _7 = Pointer_leak__String(_6_ref);
        String* p = _7;
        /* let */ {
            static String _15 = "foo";
            String *_15_ref = &_15;
            String _16 = String_copy(_15_ref);
            String* _17 = Pointer_set__String(p, _16);
            String* _ = _17;
            /* () */
        }
        String _26 = Pointer_to_MINUS_value__String(p);
        String _27 = StringCopy_str(_26);
        String* _28 = &_27; // ref
        IO_println(_28);
        Pointer_free__String(p);
        int _34 = 0;
        _35 = _34;
        String_delete(_27);
    }
    return _35;
}
```

As mentioned, and as w/ other Pointer functions users need to ensure the
safety of these operations themselves. For example, calling `free` on
`p` twice in the example above produces the expected double free:

```
(defn foo []
  (let-do [p (Pointer.leak "leaky")] ;; create a new pointer
    (ignore (Pointer.set p @"foo")) ;; set the pointer to "foo"
    (println* (Pointer.to-value p)) ;; convert to a Carp val to print
    (Pointer.free p) ;; finally, free it.
    (Pointer.free p) ;; !Double free!
    0))
(foo)
Compiled to 'out/Untitled' (executable)
foo
Untitled(38328,0x10d9a1dc0) malloc: *** error for object 0x7feb86c01790:
pointer being freed was not allocated
Untitled(38328,0x10d9a1dc0) malloc: *** set a breakpoint in
malloc_error_break to debug
[RUNTIME ERROR] '"out/Untitled"' exited with return value -6.
```

Still, these should come in handy in rare cases in which users need to
circumvent the type checker or borrow checker.

diff --git a/core/Pointer.carp b/core/Pointer.carp
index a662c636..4f29d587 100644
--- a/core/Pointer.carp
+++ b/core/Pointer.carp
@@ -20,6 +20,29 @@ The user will have to ensure themselves that this is a safe operation.")
   (doc from-long "converts a long integer to a pointer.")
   (deftemplate from-long (Fn [Long] (Ptr p)) "$p* $NAME(Long p)" " $DECL { return ($p*)p; }")

+  (doc set-unsafe
+    "Sets the value of a pointer."
+    "The user will have to ensure this operation is safe.")
+  (deftemplate set-unsafe (Fn [(Ptr p) (Ref a b)] (Ptr p)) "$p* $NAME($p* p, void* a)" "$DECL { *p = *($p*)a; return p;}")
+
+  (doc cast
+     "Cast a pointer to type p to a pointer to type a."
+     "The value of the `a` argument is ignored.")
+  (deftemplate cast (Fn [(Ptr p) a] (Ptr a)) "$a* $NAME($p* p, $a a)" "$DECL { *($a*)p = CARP_MALLOC(sizeof($a)); return ($a*)p;}")
+
+  (doc leak
+     "Allocate a new pointer that's a copy of the value of `Ref`"
+     "The Carp borrow checker won't delete this pointer. You will need to delete it manually by calling `Pointer.free`.")
+  (deftemplate leak (Fn [(Ref a b)] (Ptr a)) "$a* $NAME($a* r)" "$DECL { void *leak = CARP_MALLOC(sizeof($a)); memcpy(leak, r, sizeof($a)); return ($a*)leak;}")
+
+  (doc free
+     "Free a pointer."
+     "Users need to manually verify that this operation is safe.")
+  (deftemplate free (Fn [(Ptr p)] Unit) "void $NAME($p* p)" "$DECL {CARP_FREE(p);}")
+
+  (doc set "Sets the value of a pointer.")
+  (deftemplate set (Fn [(Ptr p) p] (Ptr p)) "$p* $NAME($p* p, $p a)" "$DECL { *p = a; return p;}")
+
   (defn inc [a] (Pointer.add a 1l))
   (implements inc Pointer.inc)
   (defn dec [a] (Pointer.sub a 1l))

* Pointer: Change signature of leak to make it more sensible

Instead of `leak` copying a previously allocated value, it now takes
(unmanaged) ownership of a fresh value and allocates. This makes more
sense semantically, as we're just instantiating a new pointer that won't
be managed by Carp and will leak unless freed explicitly.

Thanks to @TimDeve for the suggestion!

* Pointer: Improve apis on set and alloc

- Rename set-unsafe to align w/ naming conventions
  Most unsafe functions are prefixed with `unsafe`, not suffixed.
- Rename leak to `unsafe-alloc` to better convey its semantics (leak
  also already exists as `Unsafe.leak`.
- Remove `cast` since its use is covered by `Unsafe.coerce`.

Thanks to TimDeve and hellerve for the suggestions!

* Pointer: Make unsafe-set take ownership

* Pointer: Correctly cast in unsafe-alloc; add unsafe-realloc

Here's a short illustration of why we need `realloc` even though we
already have `Pointer.add`:

```
(defn foo []
  (let-do [p (Pointer.unsafe-alloc 2)]
    (set! p (Pointer.add p (Pointer.width (Pointer.unsafe-alloc @"foo"))))
    (ignore (Pointer.unsafe-set p @"foo"))
    (println* (Pointer.to-value (the (Ptr String) (Unsafe.coerce p))))
    (Pointer.free p)
    0))
```

This function seems fine at first glance, but since `add` returns a new
pointer, `p` is reset to the new pointer, the reference to the original
is lost, and `free` is called on a value that was never actually
allocated since `add` does not malloc.

Using unsafe-realloc, we can avoid the additional allocation:

```
(defn foo []
  (let-do [p (Pointer.unsafe-alloc 2)]
    (Pointer.unsafe-realloc p @"foo")
    (ignore (Pointer.unsafe-set p @"foo"))
    (println* (Pointer.to-value (the (Ptr String) (Unsafe.coerce p))))
    (Pointer.free p)
    0))
```

The allocation is what we care about here. One still needs to use
`Unsafe.coerce` since as far as the Carp compiler is concerned, `p` is
still a (Ptr Int) even though the corresponding c has cast it silently
to a `String` in order to reallocate.

* Pointer: Change signature of unsafe-set to align with set!

* Pointer: Change signature of `set` to align with `set!`

* Pointer: Remove unsafe-realloc

* Pointer: Update docs for unsafe-alloc and free

* System: Remove System.free

Pointer.free serves a similar function, and is more restrictive, so
we'll remove System.free. One can use `delete` or cast to a pointer and
free that way.See PR #1012 for further discussion.
2020-11-30 07:06:04 +01:00
hellerve
ef355b91d8 core: use static array for args 2020-08-24 11:20:52 +02:00
Erik Svedäng
dcca7505d1
Merge pull request #786 from hellerve/veit/move-to-templates
Move templates out of the compiler into deftemplates
2020-05-12 22:24:54 +02:00
hellerve
fe2c08c1ff core: rearrange templates 2020-05-12 21:58:40 +02:00
Jorge Acereda
9f87d17561 Ignoring system() return value produces warnings on some systems, just return it. 2020-05-11 16:08:40 +02:00
Erik Svedäng
41b450873e Carp init globals function call. 2020-03-23 10:31:58 +01:00
sdilts
77614b21d9 Add errno to System.carp
+ Error values included are those that can be set from calling `fopen`
+ Change order of imports so that the System module is available before the IO module
2019-11-01 17:26:56 -06:00
Jorge Acereda
554b9df849 Use abort() for assertions. 2019-07-29 21:48:20 +02:00
Scott Olsen
65d612939a
Fix doc for get-args-len
I was running through the docs and it seemed like get-arg was incorrectly documented based on the signature. It looks like the doc for get-args-len was reassigned to get-arg.
2019-04-16 17:49:31 -04:00
hellerve
59f636f051 core: Random.seed with a good default, rename old version to Random.seed-from 2018-10-19 10:31:00 +02:00
hellerve
99fb38de73 core: add assert-signal 2018-05-23 15:13:13 +02:00
hellerve
a55c953396 core: add inspection of forked processes (references #235) 2018-05-23 13:58:04 +02:00
hellerve
032249b342 core: add random module (referencing #227) 2018-05-22 19:34:38 +02:00
hellerve
db0a3d4417 core: document integer, interfaces, pattern, safeint, and system 2018-05-12 16:08:48 +02:00
hellerve
b9ae704dcc all: change system argument api 2018-04-04 09:00:20 +02:00
hellerve
4d70811479 all: add System.args 2018-04-03 17:51:37 +02:00
Erik Svedäng
605a724765 Fixed memory leak in 'from-chars'. 2018-03-12 14:56:05 +01:00
Erik Svedäng
fcc01ff268 Some new functions and macros. 2018-03-11 14:53:50 +01:00
hellerve
890a2eab1e core: rename System.srand to System.seed-random 2018-02-27 15:12:25 +01:00
hellerve
01f366f2c8 core: remove interdependencies between modules 2018-02-27 15:10:42 +01:00
hellerve
b7ea8d1487 core: namespaced split-up carp headers 2018-02-27 15:08:39 +01:00
hellerve
f56b1ff93f core: split up core.h, installment 1 2018-02-27 15:08:36 +01:00
Erik Svedäng
36274a29d3 Made System.exit return 'a' instead of (). 2018-02-08 22:13:27 +01:00
Erik Svedäng
936dd8b26c Changed type of member getter method to always returning a Ref (used to be non-ref for primitive types). 2018-01-26 21:23:29 +01:00
Erik Svedäng
b8c1da3e3b Sleeping functions. 2017-12-25 16:51:23 +01:00
Erik Svedäng
57bb9a7469 Extracted out Debug module. 2017-12-23 14:10:44 +01:00
Erik Svedäng
bce28c65cd This might work. 2017-12-23 08:58:57 +01:00
Erik Svedäng
2dbcfac61b Bunch of bug fixes and stuff. 2017-10-18 13:02:44 +02:00
Erik Svedäng
c80526cfaa REPLACE WITH HASKELL VERSION 2017-06-26 11:15:03 +02:00