Skip to content

Commit

Permalink
work on string representation
Browse files Browse the repository at this point in the history
  • Loading branch information
johnynek committed Nov 15, 2024
1 parent 7e04ff8 commit 9da834e
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 17 deletions.
41 changes: 25 additions & 16 deletions c_runtime/bosatsu_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,7 @@
#include <stdatomic.h>
#include <stdlib.h>

#define DEFINE_RC_STRUCT(name, fields) \
struct name { \
atomic_int ref_count; \
FreeFn free; \
fields \
}; \
typedef struct name name

#define DEFINE_RC_ENUM(name, fields) \
struct name { \
atomic_int ref_count; \
FreeFn free; \
ENUM_TAG tag; \
fields \
}; \
typedef struct name name
#define DEFINE_RC_ENUM(name, fields) DEFINE_RC_STRUCT(name, ENUM_TAG tag; fields)

DEFINE_RC_STRUCT(RefCounted,);

Expand Down Expand Up @@ -49,6 +34,9 @@ void free_closure(Closure1Data* s) {
DEFINE_RC_ENUM(Enum0,);

DEFINE_RC_STRUCT(External, void* external; FreeFn ex_free;);

DEFINE_RC_STRUCT(BSTS_String, size_t len; char* bytes;);

// A general structure for a reference counted memory block
// it is always allocated with len BValue array immediately after
typedef struct _Node {
Expand Down Expand Up @@ -149,6 +137,27 @@ void* get_external(BValue v) {
return rc->external;
}

void free_string(void* str) {
BSTS_String* casted = (BSTS_String*)str;
free(casted->bytes);
free(str);
}

// this copies the bytes in, it does not take ownership
BValue bsts_copy_string_from_utf8_bytes(size_t len, char* bytes) {
BSTS_String* str = malloc(sizeof(BSTS_String));
char* bytes_copy = malloc(sizeof(char) * len);
for(size_t i = 0; i < len; i++) {
bytes_copy[i] = bytes[i];
}
str->len = len;
str->bytes = bytes_copy;
atomic_init(&str->ref_count, 1);
str->free = (FreeFn)free_string;

return (BValue)str;
}

// Function to determine the type of the given value pointer and clone if necessary
BValue clone_value(BValue value) {
if (IS_POINTER(value)) {
Expand Down
23 changes: 23 additions & 0 deletions c_runtime/bosatsu_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ when it comes to functions there are three types:
b. static closure (something that closes over static things, ideally we would optimize this away): ends with 10
c. refcounted closure: ends with 00
Nat-like values are represented by positive integers encoded as PURE_VALUE such that
NAT(x) = (x << 1) | 1, since we don't have enough time to increment through 2^{63} values
this is a safe encoding.
Char values are stored as unicode code points with a trailing 1.
String values encodings, string values are like ref-counted structs with
a length and char* holding the utf-8 bytes. We could also potentially optimize
short strings by packing them literally into 63 bits with a length.
Integer values are either pure values (signed values packed into 63 bits),
or ref-counted big integers
We need to know which case we are in because in generic context we need to know
how to clone values.
*/
Expand All @@ -38,6 +51,14 @@ how to clone values.
#define TO_POINTER(ptr) ((uintptr_t)(ptr) & ~TAG_MASK)
#define STATIC_PUREFN(ptr) (BValue*)((uintptr_t)(ptr) | PURE_VALUE_TAG)

#define DEFINE_RC_STRUCT(name, fields) \
struct name { \
atomic_int ref_count; \
FreeFn free; \
fields \
}; \
typedef struct name name

typedef void* BValue;
typedef uint32_t ENUM_TAG;
#include "bosatsu_decls_generated.h"
Expand Down Expand Up @@ -67,6 +88,8 @@ BValue get_enum_index(BValue v, int idx);
// This one is not auto generated because it can always be fit into the BValue directly
BValue alloc_enum0(ENUM_TAG tag);

BValue bsts_string_from_utf8_bytes(size_t len, char* bytes);

BValue alloc_external(void* eval, FreeFn free_fn);
void* get_external(BValue v);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import org.bykn.bosatsu.Identifier.Bindable
import org.typelevel.paiges.Doc

import cats.syntax.all._
import org.bykn.bosatsu.Lit.Chr
import org.bykn.bosatsu.Lit.Str

object ClangGen {
sealed abstract class Error
Expand Down Expand Up @@ -193,7 +195,17 @@ object ClangGen {
)
}

def literal(lit: Lit): Code.Expression = ???
def literal(lit: Lit): Code.Expression =
lit match {
case Lit.Chr(asStr) =>
// encoded as integers in pure values
???
case Lit.Integer(toBigInteger) =>
???
case Lit.Str(toStr) =>
// convert to utf8 and then to a literal array of bytes
???
}

def innerApp(app: App): T[Code.ValueLike] =
app match {
Expand Down

0 comments on commit 9da834e

Please sign in to comment.