Fun API Documentation 0.42.1
The programming language that makes you have fun!
Loading...
Searching...
No Matches
fun.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
10/**
11 * @file fun.c
12 * @brief Command-line interface and entry point for the Fun interpreter.
13 *
14 * Main entry point for the Fun language interpreter.
15 * Builds a CLI that runs a script file if provided; otherwise starts the REPL
16 * when compiled with FUN_WITH_REPL enabled.
17 */
18
19#include "bytecode.h"
20#include "parser.h"
21#include "vm.h"
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26#ifdef FUN_WITH_REPL
27#include "repl.h"
28#endif
29
30#ifndef FUN_VERSION
31#define FUN_VERSION "0.0.0-dev"
32#endif
33
34/**
35 * @brief Print command-line usage instructions to stdout.
36 *
37 * The usage varies depending on whether the binary was built with
38 * FUN_WITH_REPL enabled.
39 *
40 * @param prog Program name/path used in usage lines. May be NULL.
41 */
42static void print_usage(const char *prog) {
43 printf("Fun %s\n", FUN_VERSION);
44 printf("Usage:\n");
45#ifdef FUN_WITH_REPL
46 printf(" %s [--trace|-t] [--repl-on-error] [script.fun]\n", prog ? prog : "fun");
47 printf(" %s --help | -h\n", prog ? prog : "fun");
48 printf(" %s --version | -V\n", prog ? prog : "fun");
49 printf("\n");
50 printf("Options:\n");
51 printf(" --trace, -t Print executed ops and stack tops during run\n");
52 printf(" --repl-on-error Enter interactive REPL on runtime error with stack preserved\n\n");
53 printf("When no script is provided, a REPL starts. Submit an empty line to execute the buffer.\n");
54#else
55 printf(" %s [--trace|-t] <script.fun>\n", prog ? prog : "fun");
56 printf(" %s --help | -h\n", prog ? prog : "fun");
57 printf(" %s --version | -V\n", prog ? prog : "fun");
58 printf("\n");
59 printf("Options:\n --trace, -t Print executed ops and stack tops during run\n\n");
60 printf("REPL is disabled in this build. Please provide a script file to run.\n");
61#endif
62}
63
64/**
65 * @brief Program entry point for the Fun interpreter.
66 *
67 * Parses CLI options, compiles and runs a script file if provided, or launches
68 * the REPL when enabled and no script is given. Exposes script arguments to
69 * the program via FUN_ARGC/FUN_ARGV_i/FUN_ARGS environment variables.
70 *
71 * @param argc Argument count.
72 * @param argv Argument vector; argv[0] is used to expose FUN_EXECUTABLE.
73 * @return Process exit code, typically taken from the VM after execution.
74 */
75int main(int argc, char **argv) {
76 /* Set FUN_EXECUTABLE environment variable to the path of this binary */
77 setenv("FUN_EXECUTABLE", argv[0], 1);
78
79 VM vm;
80 vm_init(&vm);
81
82 int argi = 1;
83 for (; argi < argc; ++argi) {
84 const char *arg = argv[argi];
85 if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
86 print_usage(argv[0]);
87 return 0;
88 }
89 if (strcmp(arg, "--version") == 0 || strcmp(arg, "-V") == 0) {
90 printf("Fun %s\n", FUN_VERSION);
91 return 0;
92 }
93 if (strcmp(arg, "--trace") == 0 || strcmp(arg, "-t") == 0) {
94 vm.trace_enabled = 1;
95 continue;
96 }
97#ifdef FUN_WITH_REPL
98 if (strcmp(arg, "--repl-on-error") == 0) {
99 vm.repl_on_error = 1;
100 vm.on_error_repl = fun_run_repl; /* provide REPL entry to core VM */
101 continue;
102 }
103#endif
104 /* first non-option assumed to be script path */
105 break;
106 }
107
108#ifndef FUN_WITH_REPL
109 if (argi >= argc) {
110 fprintf(stderr, "Error: REPL is disabled. Please provide a script to run.\n");
111 print_usage(argv[0]);
112 return 2;
113 }
114#endif
115
116 if (argi < argc) {
117 const char *path = argv[argi];
118
119 /* Collect script arguments (everything after script path) and expose via env vars */
120 int sargi = argi + 1; /* first script arg following the script path */
121 int sargc = (sargi < argc) ? (argc - sargi) : 0;
122
123 /* Export FUN_ARGC */
124 {
125 char buf[32];
126 snprintf(buf, sizeof(buf), "%d", sargc);
127 setenv("FUN_ARGC", buf, 1);
128 }
129
130 /* Export FUN_ARGV_i */
131 for (int i = 0; i < sargc; ++i) {
132 char key[32];
133 snprintf(key, sizeof(key), "FUN_ARGV_%d", i);
134 setenv(key, argv[sargi + i], 1);
135 }
136
137 /* Optional: space-joined convenience string FUN_ARGS */
138 if (sargc > 0) {
139 size_t total = 0;
140 for (int i = 0; i < sargc; ++i) {
141 total += strlen(argv[sargi + i]) + 1; /* +1 for space or NUL */
142 }
143 char *joined = (char *)malloc(total);
144 if (joined) {
145 joined[0] = '\0';
146 for (int i = 0; i < sargc; ++i) {
147 strcat(joined, argv[sargi + i]);
148 if (i + 1 < sargc) strcat(joined, " ");
149 }
150 setenv("FUN_ARGS", joined, 1);
151 free(joined);
152 }
153 } else {
154 /* Ensure FUN_ARGS is at least cleared for consistency */
155 setenv("FUN_ARGS", "", 1);
156 }
157
159 if (!bc) {
160 fprintf(stderr, "Failed to compile script: %s\n", path);
161 return 1;
162 }
163
164 vm_run(&vm, bc);
165 vm_print_output(&vm);
166 vm_clear_output(&vm);
167 bytecode_free(bc);
168 return vm.exit_code;
169 }
170
171#ifdef FUN_WITH_REPL
172 return fun_run_repl(&vm);
173#else
174 fprintf(stderr, "Internal error: REPL not available in this build.\n");
175 return 2;
176#endif
177}
void bytecode_free(Bytecode *bc)
Free a Bytecode and all memory it owns.
Definition bytecode.c:104
Definitions for the Fun VM bytecode: opcodes, instruction format, and bytecode container API.
#define FUN_VERSION
Definition fun.c:31
static void print_usage(const char *prog)
Print command-line usage instructions to stdout.
Definition fun.c:42
int main(void)
Build and execute a demo bytecode program and print results.
Definition fun_test.c:44
Bytecode * parse_file_to_bytecode(const char *path)
Parse a .fun source file and return compiled bytecode.
Definition parser.c:7683
Public API for parsing Fun source into bytecode.
int fun_run_repl(VM *vm)
Run the interactive Fun REPL session.
Definition repl.c:1310
Interactive Read-Eval-Print Loop (REPL) entry point.
The Fun virtual machine state.
Definition vm.h:112
int repl_on_error
Definition vm.h:137
int(* on_error_repl)(struct VM *vm)
Definition vm.h:138
int trace_enabled
Definition vm.h:136
int exit_code
Definition vm.h:134
void vm_init(VM *vm)
Initialize a VM instance to its default state.
Definition vm.c:745
#define fprintf
Definition vm.c:194
void vm_clear_output(VM *vm)
Clear the VM's buffered output values and partial flags.
Definition vm.c:359
void vm_print_output(VM *vm)
Print the VM's buffered output values to stdout.
Definition vm.c:832
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...