Fun 0.41.5
The programming language that makes You have fun
Loading...
Searching...
No Matches
fun_test.c
Go to the documentation of this file.
1/*
2 * This file is part of the Fun programming language.
3 * https://fun-lang.xyz/
4 *
5 * Copyright 2025 Johannes Findeisen <you@hanez.org>
6 * Licensed under the terms of the Apache-2.0 license.
7 * https://opensource.org/license/apache-2-0
8 */
9
14
15#include "bytecode.h"
16#include "value.h"
17#include "vm.h"
18#include <math.h>
19#include <stdio.h>
20
27#define ASSERT_EQ(val, expected) \
28 if ((val).type != VAL_INT || (val).i != (expected)) { \
29 fprintf(stderr, "Assertion failed: expected %lld, got ", (long long)(expected)); \
30 print_value(&(val)); \
31 printf("\n"); \
32 return 1; \
33 }
34
44int main(void) {
45 VM vm;
46 vm_init(&vm);
47
49
50 // constants
51 int c0 = bytecode_add_constant(bc, make_int(0));
52 int c1 = bytecode_add_constant(bc, make_int(1));
53 int c2 = bytecode_add_constant(bc, make_int(2));
54 int c3 = bytecode_add_constant(bc, make_int(3));
55 int c10 = bytecode_add_constant(bc, make_int(10));
56 int c42 = bytecode_add_constant(bc, make_int(42));
57 int cf3_2 = bytecode_add_constant(bc, make_float(3.2));
58 int cf3_5 = bytecode_add_constant(bc, make_float(3.5));
59 int cf3_8 = bytecode_add_constant(bc, make_float(3.8));
60 int cfn3_2 = bytecode_add_constant(bc, make_float(-3.2));
61 int cfn3_5 = bytecode_add_constant(bc, make_float(-3.5));
62 int cfn3_8 = bytecode_add_constant(bc, make_float(-3.8));
63 int cf0 = bytecode_add_constant(bc, make_float(0.0));
64 int cf1 = bytecode_add_constant(bc, make_float(1.0));
65 int cf5 = bytecode_add_constant(bc, make_float(5.0));
66 int c4 = bytecode_add_constant(bc, make_int(4));
67 int c9 = bytecode_add_constant(bc, make_int(9));
68 int c48 = bytecode_add_constant(bc, make_int(48));
69 int c18 = bytecode_add_constant(bc, make_int(18));
70 int c21 = bytecode_add_constant(bc, make_int(21));
71 int c6 = bytecode_add_constant(bc, make_int(6));
72 int c15 = bytecode_add_constant(bc, make_int(15));
73 int c16 = bytecode_add_constant(bc, make_int(16));
74 int cneg5 = bytecode_add_constant(bc, make_int(-5));
75 int c7 = bytecode_add_constant(bc, make_int(7));
76
77 // ---------- Arithmetic ----------
80 bytecode_add_instruction(bc, OP_ADD, 0); // 42+1=43
82
85 bytecode_add_instruction(bc, OP_SUB, 0); // 10-3=7
87
90 bytecode_add_instruction(bc, OP_MUL, 0); // 2*3=6
92
95 bytecode_add_instruction(bc, OP_DIV, 0); // 10/2=5
97
100 bytecode_add_instruction(bc, OP_MOD, 0); // 10%3=1
102
103 // ---------- Comparisons ----------
106 bytecode_add_instruction(bc, OP_LT, 0); // 1<2=1
108
111 bytecode_add_instruction(bc, OP_LTE, 0); // 2<=2=1
113
116 bytecode_add_instruction(bc, OP_GT, 0); // 3>2=1
118
121 bytecode_add_instruction(bc, OP_GTE, 0); // 2>=2=1
123
126 bytecode_add_instruction(bc, OP_EQ, 0); // 2==2=1
128
131 bytecode_add_instruction(bc, OP_NEQ, 0); // 2!=3=1
133
134 // ---------- Logical ----------
137 bytecode_add_instruction(bc, OP_AND, 0); // 1&&0=0
139
142 bytecode_add_instruction(bc, OP_OR, 0); // 1||0=1
144
146 bytecode_add_instruction(bc, OP_NOT, 0); // !0=1
148
149 // ---------- Stack ----------
151 bytecode_add_instruction(bc, OP_DUP, 0); // duplicate 1
152 bytecode_add_instruction(bc, OP_ADD, 0); // 1+1=2
154
157 bytecode_add_instruction(bc, OP_SWAP, 0); // swap top two
158 bytecode_add_instruction(bc, OP_PRINT, 0); // top=1
159
161 bytecode_add_instruction(bc, OP_POP, 0); // dApache-2.0ard 1 (stack now empty)
162
163 // ---------- Rounding (math.h) demo ----------
164 // floor/ceil/trunc/round on representative values
165 int start_round_demo = bc->instr_count;
166 (void)start_round_demo;
167
168 // +3.2
181
182 // +3.5
186
187 // -3.5
191
192 // -3.2
199
200 // integers should be unchanged
204
205 // ---------- Transcendentals demo ----------
206 // sin(0)=0
210 // cos(0)=1
214 // tan(0)=0
218 // exp(0)=1
222 // log(1)=0
226 // log10(1)=0
230 // sqrt(9)=3
234
235 // ---------- Integer math (gcd/lcm/isqrt/sign) demo ----------
236 // gcd(48,18)=6
241
242 // lcm(21,6)=42
247
248 // isqrt cases: 0, 1, 15->3, 16->4
261
262 // sign(-5)=-1, sign(0)=0, sign(7)=1
272
273 // ---------- fmin/fmax demo ----------
274 // fmin(3.2, 4) -> 3.2
279 // fmax(3.2, 4) -> 4
284 // NaN cases
285 double nanv = NAN;
286 int cNaN = bytecode_add_constant(bc, make_float(nanv));
287 // fmin(NaN, 5.0) -> 5.0
292 // fmax(NaN, 5.0) -> 5.0
297 // fmin(5.0, NaN) -> 5.0
302 // fmax(5.0, NaN) -> 5.0
307 // fmin(NaN, NaN) -> NaN (prints as nan)
312
313 // ---------- HALT ----------
315
316 printf("=== Bytecode dump ===\n");
317 for (int i = 0; i < bc->instr_count; ++i) {
318 Instruction instr = bc->instructions[i];
319 printf("instr %3d: opcode=%2d operand=%d\n", i, instr.op, instr.operand);
320 }
321 printf("=====================\n");
322
323 // run VM
324 vm_run(&vm, bc);
325
326 printf("All tests executed. Output count: %d\n", vm.output_count);
327
328 vm_clear_output(&vm);
329 bytecode_free(bc);
330 return 0;
331}
Bytecode * bytecode_new(void)
Allocate and initialize an empty Bytecode object.
Definition bytecode.c:27
int bytecode_add_instruction(Bytecode *bc, OpCode op, int32_t operand)
Append a single instruction to the instruction stream.
Definition bytecode.c:62
void bytecode_free(Bytecode *bc)
Free a Bytecode and all memory it owns.
Definition bytecode.c:92
int bytecode_add_constant(Bytecode *bc, Value v)
Append a constant to a Bytecode's constant table.
Definition bytecode.c:48
Definitions for the Fun VM bytecode: opcodes, instruction format, and bytecode container API.
@ OP_GCD
Definition bytecode.h:268
@ OP_TAN
Definition bytecode.h:261
@ OP_TRUNC
Definition bytecode.h:255
@ OP_CEIL
Definition bytecode.h:254
@ OP_EQ
Definition bytecode.h:53
@ OP_LTE
Definition bytecode.h:50
@ OP_NEQ
Definition bytecode.h:54
@ OP_ISQRT
Definition bytecode.h:270
@ OP_FMAX
Definition bytecode.h:275
@ OP_FMIN
Definition bytecode.h:274
@ OP_SWAP
Definition bytecode.h:76
@ OP_NOT
Definition bytecode.h:73
@ OP_SQRT
Definition bytecode.h:265
@ OP_MOD
Definition bytecode.h:70
@ OP_SIGN
Definition bytecode.h:271
@ OP_DUP
Definition bytecode.h:75
@ OP_LCM
Definition bytecode.h:269
@ OP_COS
Definition bytecode.h:260
@ OP_SUB
Definition bytecode.h:45
@ OP_DIV
Definition bytecode.h:47
@ OP_LT
Definition bytecode.h:49
@ OP_ROUND
Definition bytecode.h:256
@ OP_PRINT
Definition bytecode.h:63
@ OP_LOAD_CONST
Definition bytecode.h:37
@ OP_ADD
Definition bytecode.h:44
@ OP_MUL
Definition bytecode.h:46
@ OP_LOG10
Definition bytecode.h:264
@ OP_SIN
Definition bytecode.h:259
@ OP_GT
Definition bytecode.h:51
@ OP_GTE
Definition bytecode.h:52
@ OP_HALT
Definition bytecode.h:65
@ OP_AND
Definition bytecode.h:71
@ OP_LOG
Definition bytecode.h:263
@ OP_OR
Definition bytecode.h:72
@ OP_FLOOR
Definition bytecode.h:253
@ OP_EXP
Definition bytecode.h:262
@ OP_POP
Definition bytecode.h:56
int main(void)
Build and execute a demo bytecode program and print results.
Definition fun_test.c:44
Instruction * instructions
Definition bytecode.h:294
int instr_count
Definition bytecode.h:295
OpCode op
Definition bytecode.h:289
int32_t operand
Definition bytecode.h:290
The Fun virtual machine state.
Definition vm.h:110
int output_count
Definition vm.h:120
Value make_float(double v)
Construct a Value representing a double-precision float.
Definition value.c:64
Value make_int(int64_t v)
Construct a Value representing a 64-bit integer.
Definition value.c:51
Defines the Value type and associated functions for the Fun VM.
void vm_init(VM *vm)
Initialize a VM instance to its default state.
Definition vm.c:714
void vm_clear_output(VM *vm)
Clear the VM's buffered output values and partial flags.
Definition vm.c:349
Core virtual machine data structures and public VM API.
void vm_run(VM *vm, Bytecode *entry)
Execute the provided entry bytecode in the VM. Pushes an initial frame and runs until HALT or an unre...