Serene Runtime 1.0.0
C runtime for the Serene programming language
Loading...
Searching...
No Matches
core.h
Go to the documentation of this file.
1/* -*- C -*-
2 * Serene programming language
3 * Copyright (C) 2019-2026 Sameer Rahmani <[email protected]>
4 *
5 * This library is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20
21#include <stddef.h>
22#include <stdint.h>
23
24#include "llvm-c/Core.h"
25#include "llvm-c/Types.h"
26#include "serene/rt/impl/seq.h"
27
28typedef struct srn_context_t srn_context_t;
29typedef struct srn_expr_t srn_expr_t;
30typedef struct srn_value_t srn_value_t;
31typedef struct srn_closure_t srn_closure_t;
32typedef struct srn_error_t srn_error_t;
36typedef struct srn_list_t srn_list_t;
38typedef struct srn_seq_t srn_seq_t;
39typedef struct srn_map_t srn_map_t;
40
41// -----------------------------------------------------------------------------
42// Internal ABI
43// In C we can't mark fastcc portably; we treat codeptrs as plain fn ptrs.
44// LLVM IR will set calling convention = fastcc on definitions & calls.
45// -----------------------------------------------------------------------------
46typedef srn_value_t *(*srn_fnptr_t)(srn_context_t *ctx, srn_value_t *argv,
47 uint32_t argc);
48
49typedef struct srn_src_location_t {
50 /// ID of the source buffer that is registered with the source manager
51 uint16_t buffer_id;
52 uint16_t line;
53 uint16_t col;
54 uint16_t len;
56
57typedef struct srn_metadata_t {
58 /// `nullptr` is a valid value and represents an unknown location.
60 /// An optional pointer to the original and raw expression. We use this
61 /// to track what value/expression is a descendant of which expression.
64
65/// We use this for testing
66static srn_metadata_t absurd_metadata = {nullptr, nullptr};
67
68// -----------------------------------------------------------------------------
69// Syntaces
70// This is type will be represented in LLVM like:
71// %srn_syntax_t = type { i64, ptr, i64 } ; { tag, loc, payload }
72// -----------------------------------------------------------------------------
88
89typedef struct srn_syntax_t {
92 /// IMPORTANT NOTE: The size of this union should never be larger than a word
93 union {
94 /// For syntax only, we represent numbers as a strings,
95 const char *symbol;
96 const char *number;
97 const char *string;
100 const char *keyword;
104 } as;
106
107// -----------------------------------------------------------------------------
108// Values
109// This is type will be represented in LLVM like:
110// %srn_value_t = type { i64, ptr, i64 } ; { tag, loc, payload }
111// -----------------------------------------------------------------------------
130
131typedef struct srn_value_t {
134 /// IMPORTANT NOTE: The size of this union should never be larger than a word
135 union {
136 /// We represent all the immidiate numbers with this field and cast as we
137 /// to an appropriate type. It might change in the future.
138 int64_t i64;
139 double f64;
149 } as;
151
152#define SIZE_OF_VALUE_PALYLOAD 8
153_Static_assert(sizeof(((srn_value_t *)0)->as) == SIZE_OF_VALUE_PALYLOAD,
154 "srn_value_t's union has the wrong size");
155
156static srn_value_t nil_v = {.type = VNil};
157static srn_value_t true_v = {.type = VTrue};
158static srn_value_t false_v = {.type = VFalse};
159
160#define TYPE(value_ref) ((value_ref)->type)
161#define METADATA(value_ref) ((value_ref)->metadata)
162#define IS_A(value_ref, field) (TYPE(value_ref) == (field))
163#define IS_TRUE(value_ref) (TYPE(value_ref) == VTrue)
164#define IS_FALSE(value_ref) (TYPE(value_ref) == VFalse)
165#define IS_NIL(value_ref) (TYPE(value_ref) == VNil)
166
167#define AS_I64(value_ref) ((value_ref)->as.i64)
168#define AS_F64(value_ref) ((value_ref)->as.f64)
169#define AS_CLOSURE(value_ref) ((value_ref)->as.closure)
170#define AS_NS(value_ref) ((value_ref)->as.ns)
171#define AS_STRING(value_ref) ((value_ref)->as.string)
172#define AS_SYMBOL(value_ref) ((value_ref)->as.symbol)
173#define AS_ERROR(value_ref) ((value_ref)->as.error)
174#define AS_LIST(value_ref) ((value_ref)->as.list)
175#define AS_KEYWORD(value_ref) ((value_ref)->as.keyword)
176#define AS_SEQ(value_ref) ((value_ref)->as.seq)
177#define AS_MAP(value_ref) ((value_ref)->as.map)
178
179/// Creates a new serene value. We always heap allocate the values. So, ANY
180/// value creation should go through this function
181[[nodiscard]] [[gnu::nonnull(1)]] [[gnu::returns_nonnull]]
183 srn_metadata_t *metadata, void *payload);
184
185/// LLVM type for srn_value_t in LLVM IR. { i64, ptr, i64 }
186static inline LLVMTypeRef srn_llvm_value_t(LLVMContextRef llctx) {
187 LLVMTypeRef i64t = LLVMInt64TypeInContext(llctx);
188
189 // opaque ptr
190 LLVMTypeRef i8t = LLVMInt8TypeInContext(llctx);
191 LLVMTypeRef ptrt = LLVMPointerType(i8t, 0);
192
193 LLVMTypeRef fields[3];
194 fields[0] = i64t; // type tag (srn_value_tag_t as i64)
195 fields[1] = ptrt; // loc pointer
196 fields[2] = i64t; // payload (the union)
197
198 LLVMTypeRef st = LLVMStructCreateNamed(llctx, "srn_value_t");
199 LLVMStructSetBody(st, fields, 3, 0);
200 return st;
201}
static LLVMTypeRef srn_llvm_value_t(LLVMContextRef llctx)
LLVM type for srn_value_t in LLVM IR. { i64, ptr, i64 }.
Definition core.h:186
struct srn_string_t srn_string_t
Definition core.h:34
srn_value_t * srn_value_make(srn_context_t *ctx, srn_value_tag_t tag, srn_metadata_t *metadata, void *payload)
Creates a new serene value.
Definition core.c:24
struct srn_keyword_t srn_keyword_t
Definition core.h:37
static srn_metadata_t absurd_metadata
We use this for testing.
Definition core.h:66
struct srn_namespace_t srn_namespace_t
Definition core.h:33
static srn_value_t false_v
Definition core.h:158
srn_value_tag_e
Definition core.h:112
@ VQuote
Definition core.h:120
@ VSeq
Definition core.h:119
@ VNamespace
Definition core.h:122
@ VClosure
Definition core.h:121
@ VNil
Definition core.h:113
@ VList
Definition core.h:118
@ VFalse
Definition core.h:115
@ VF64
Definition core.h:117
@ VSymbol
Definition core.h:124
@ VI64
Definition core.h:116
@ VMap
Definition core.h:126
@ VError
VError should be last.
Definition core.h:128
@ VKeyword
Definition core.h:125
@ VTrue
Definition core.h:114
@ VString
Definition core.h:123
struct srn_map_t srn_map_t
Definition core.h:39
enum srn_syntax_tag_e srn_syntax_tag_t
#define SIZE_OF_VALUE_PALYLOAD
Definition core.h:152
srn_syntax_tag_e
Definition core.h:73
@ SQuote
Definition core.h:81
@ SKeyword
Definition core.h:83
@ SFalse
Definition core.h:76
@ SSymbol
Definition core.h:77
@ SMap
Definition core.h:84
@ SNumber
Definition core.h:78
@ SList
Definition core.h:79
@ SNil
Definition core.h:74
@ SError
SError should be last.
Definition core.h:86
@ SString
Definition core.h:82
@ SSeq
Definition core.h:80
@ STrue
Definition core.h:75
struct srn_error_t srn_error_t
Definition core.h:32
struct srn_symbol_t srn_symbol_t
Definition core.h:35
static srn_value_t true_v
Definition core.h:157
struct srn_expr_t srn_expr_t
Definition core.h:29
struct srn_seq_t srn_seq_t
Definition core.h:38
struct srn_list_t srn_list_t
Definition core.h:36
static srn_value_t nil_v
Definition core.h:156
enum srn_value_tag_e srn_value_tag_t
This is an implementation of bit - partitioned, persistent, immutable sequence For more information,...
Definition seq.h:155
A keyword: just a name.
Definition keywords.h:29
Since all the values are immutable and persistent.
Definition lists.h:36
A persistent, immutable map.
Definition maps.h:29
srn_expr_t * raw_expr
An optional pointer to the original and raw expression.
Definition core.h:62
srn_src_location_t * loc
nullptr is a valid value and represents an unknown location.
Definition core.h:59
A persistent, immutable, indexed sequence.
Definition seqs.h:27
uint16_t buffer_id
ID of the source buffer that is registered with the source manager.
Definition core.h:51
uint16_t line
Definition core.h:52
uint16_t len
Definition core.h:54
uint16_t col
Definition core.h:53
const char * string
Definition core.h:97
const char * number
Definition core.h:96
seq_t * seq
Definition core.h:101
srn_metadata_t * metadata
Definition core.h:91
union srn_syntax_t::@333325137367112222275110336355257173264057161216 as
IMPORTANT NOTE: The size of this union should never be larger than a word.
seq_t * list
Definition core.h:99
struct srn_syntax_t * quote
Definition core.h:103
const char * symbol
For syntax only, we represent numbers as a strings,.
Definition core.h:95
seq_t * map
Definition core.h:102
const char * keyword
Definition core.h:100
srn_syntax_tag_t type
Definition core.h:90
srn_error_t * error
Definition core.h:98
srn_metadata_t * metadata
Definition core.h:133
srn_namespace_t * ns
Definition core.h:141
srn_list_t * list
Definition core.h:145
int64_t i64
We represent all the immidiate numbers with this field and cast as we to an appropriate type.
Definition core.h:138
double f64
Definition core.h:139
srn_seq_t * seq
Definition core.h:147
union srn_value_t::@033047061046230251001111174367071167226300135003 as
IMPORTANT NOTE: The size of this union should never be larger than a word.
srn_closure_t * closure
Definition core.h:140
srn_error_t * error
Definition core.h:144
srn_map_t * map
Definition core.h:148
srn_symbol_t * symbol
Definition core.h:143
srn_value_tag_t type
Definition core.h:132
srn_keyword_t * keyword
Definition core.h:146
srn_string_t * string
Definition core.h:142