Fun 0.41.5
The programming language that makes you have fun!
Loading...
Searching...
No Matches
parser.c File Reference

Implements the Fun language parser that converts source code to bytecode. More...

#include "parser.h"
#include "value.h"
#include "vm.h"
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parser_utils.c"
Include dependency graph for parser.c:

Go to the source code of this file.

Data Structures

struct  LocalEnv
struct  LoopCtx

Macros

#define TYPE_META_STRING   10001
 Type metadata tag used for string enforcement in declared types.
#define TYPE_META_BOOLEAN   10002
 Type metadata tag used for boolean enforcement in declared types.
#define TYPE_META_NIL   10003
 Type metadata tag indicating explicit nil type.
#define TYPE_META_CLASS   10004
 Type metadata tag marking class/instance values.
#define TYPE_META_FLOAT   10005
 Type metadata tag marking floating point numbers.
#define TYPE_META_ARRAY   10006
 Type metadata tag marking array values.
#define MAP_TYPE_KIND(t)

Typedefs

typedef struct LoopCtx LoopCtx

Functions

char * preprocess_includes_with_path (const char *src, const char *current_path)
 Preprocess includes with a known file path to improve span markers.
static void skip_to_eol (const char *src, size_t len, size_t *pos)
 Advance position to the end of the current line, validating tail.
static int read_line_start (const char *src, size_t len, size_t *pos, int *out_indent)
 Read the start of a logical line and compute indentation.
static void parse_block (Bytecode *bc, const char *src, size_t len, size_t *pos, int current_indent)
 Parse a block of statements at a given indentation level.
static int env_truthy (const char *name)
 Interpret an environment variable as a boolean flag.
static int fun_debug_enabled (void)
 Determine whether parser/compiler debug tracing is enabled.
static void parser_fail (size_t pos, const char *fmt,...)
 Record a parser/compiler error at a given source position.
static void calc_line_col (const char *src, size_t len, size_t pos, int *out_line, int *out_col)
 Compute one-based line and column from a byte position.
static void ns_aliases_reset (void)
 Reset and free all tracked namespace aliases.
static void ns_aliases_scan (const char *src, size_t len)
 Scan preprocessed source for namespace alias markers.
static int is_ns_alias (const char *name)
 Check whether an identifier is a registered namespace alias.
static int sym_find (const char *name)
 Find a global symbol index by name.
static int sym_index (const char *name)
 Get or create a global symbol index for a name.
static int name_in_outer_envs (const char *name)
 Check whether a local name exists in any outer function environment.
static int local_find (const char *name)
 Find the index of a local variable in the current function.
static int local_add (const char *name)
 Add a new local variable to the current function environment.
static int emit_expression (Bytecode *bc, const char *src, size_t len, size_t *pos)
 Parse and emit a full expression using precedence climbing.
static int emit_primary (Bytecode *bc, const char *src, size_t len, size_t *pos)
 Parse and emit bytecode for primary expressions.
static int emit_unary (Bytecode *bc, const char *src, size_t len, size_t *pos)
 Parse and emit unary expressions.
static int emit_multiplicative (Bytecode *bc, const char *src, size_t len, size_t *pos)
 Parse and emit multiplicative expressions.
static int emit_additive (Bytecode *bc, const char *src, size_t len, size_t *pos)
 Parse and emit additive expressions.
static int emit_relational (Bytecode *bc, const char *src, size_t len, size_t *pos)
 Parse and emit relational expressions.
static int emit_equality (Bytecode *bc, const char *src, size_t len, size_t *pos)
 Parse and emit equality/inequality expressions.
static int emit_and_expr (Bytecode *bc, const char *src, size_t len, size_t *pos)
 Parse and emit logical AND (&&) with short-circuiting.
static int emit_or_expr (Bytecode *bc, const char *src, size_t len, size_t *pos)
 Parse and emit logical OR (||) with short-circuiting.
static int emit_conditional (Bytecode *bc, const char *src, size_t len, size_t *pos)
 Parse and emit the ternary conditional operator.
static void parse_simple_statement (Bytecode *bc, const char *src, size_t len, size_t *pos)
 Parse a single statement on the current line and emit bytecode.
static Bytecodecompile_minimal (const char *src, size_t len)
 Compile a full source buffer into bytecode.
Bytecodeparse_file_to_bytecode (const char *path)
 Parse a .fun source file and return compiled bytecode.
Bytecodeparse_string_to_bytecode (const char *source)
 Parse a source string and return compiled bytecode.
int parser_last_error (char *msgBuf, unsigned long msgCap, int *outLine, int *outCol)
 Retrieve the last parser/compiler error information, if any.

Variables

static const char * g_current_source_path = NULL
static int g_has_error = 0
static size_t g_err_pos = 0
static char g_err_msg [256]
static int g_err_line = 0
static int g_err_col = 0
static int g_temp_counter = 0
static char * g_ns_aliases [64]
static int g_ns_alias_count = 0
struct { 
   char *   names [MAX_GLOBALS
   int   types [MAX_GLOBALS
   int   is_class [MAX_GLOBALS
   int   count 
G = {{0}, {0}, {0}, 0}
static LocalEnvg_locals = NULL
static LocalEnvg_func_env_stack [64]
static int g_func_env_depth = 0
static LoopCtxg_loop_ctx = NULL

Detailed Description

Implements the Fun language parser that converts source code to bytecode.

This file contains the main parsing logic for the Fun programming language. It handles converting .fun source files into executable bytecode for the VM.

Key Features:

  • Handles shebang lines
  • Skips whitespace and comments
  • Parses string literals with both single and double quotes
  • Supports basic function definitions
  • Compiles print statements
  • Generates bytecode with proper constants and instructions

Functions:

Error Handling:

  • Returns NULL on parse errors
  • Tracks error messages and positions
  • Validates syntax before bytecode generation

Example: Bytecode *bc = parse_file_to_bytecode("example.fun"); if (bc) { vm_run(&vm, bc); bytecode_free(bc); }

Definition in file parser.c.

Macro Definition Documentation

◆ MAP_TYPE_KIND

#define MAP_TYPE_KIND ( t)
Value:
( \
((t) && strcmp((t), "string") == 0) ? 2 : ((t) && strcmp((t), "nil") == 0) ? 3 \
: ((t) && (strcmp((t), "boolean") == 0 || strcmp((t), "number") == 0 || strcmp((t), "byte") == 0 || strncmp((t), "uint", 4) == 0 || strncmp((t), "sint", 4) == 0 || strncmp((t), "int", 3) == 0)) ? 1 \
: 0)
long t
Definition sleep_ms.c:32

◆ TYPE_META_ARRAY

#define TYPE_META_ARRAY   10006

Type metadata tag marking array values.

Definition at line 127 of file parser.c.

◆ TYPE_META_BOOLEAN

#define TYPE_META_BOOLEAN   10002

Type metadata tag used for boolean enforcement in declared types.

Definition at line 119 of file parser.c.

◆ TYPE_META_CLASS

#define TYPE_META_CLASS   10004

Type metadata tag marking class/instance values.

Definition at line 123 of file parser.c.

◆ TYPE_META_FLOAT

#define TYPE_META_FLOAT   10005

Type metadata tag marking floating point numbers.

Definition at line 125 of file parser.c.

◆ TYPE_META_NIL

#define TYPE_META_NIL   10003

Type metadata tag indicating explicit nil type.

Definition at line 121 of file parser.c.

◆ TYPE_META_STRING

#define TYPE_META_STRING   10001

Type metadata tag used for string enforcement in declared types.

Definition at line 117 of file parser.c.

Typedef Documentation

◆ LoopCtx

typedef struct LoopCtx LoopCtx

Function Documentation

◆ calc_line_col()

void calc_line_col ( const char * src,
size_t len,
size_t pos,
int * out_line,
int * out_col )
static

Compute one-based line and column from a byte position.

Counts newlines up to the smaller of pos and len to derive a human-friendly (line, column) pair. Columns are one-based and reset after each newline.

Parameters
srcSource buffer.
lenSource length in bytes.
posTarget byte position within the source.
out_lineOptional out parameter for the computed line.
out_colOptional out parameter for the computed column.

Definition at line 160 of file parser.c.

◆ compile_minimal()

Bytecode * compile_minimal ( const char * src,
size_t len )
static

Compile a full source buffer into bytecode.

Preprocesses namespace aliases, handles shebangs and top-level constructs, parses the indentation-aware block and appends a final HALT instruction.

Parameters
srcSource buffer to compile (preprocessed when used via file API).
lenLength of the source buffer in bytes.
Returns
Newly allocated Bytecode on success; never NULL here (errors are recorded globally and may lead to incomplete bytecode).

Definition at line 7495 of file parser.c.

◆ emit_additive()

int emit_additive ( Bytecode * bc,
const char * src,
size_t len,
size_t * pos )
static

Parse and emit additive expressions.

Grammar: multiplicative (('+' | '-') multiplicative)*

Parameters
bcTarget bytecode.
srcSource buffer.
lenSource length.
posIn/out byte position pointer.
Returns
1 on success, 0 on error.

Definition at line 4525 of file parser.c.

◆ emit_and_expr()

int emit_and_expr ( Bytecode * bc,
const char * src,
size_t len,
size_t * pos )
static

Parse and emit logical AND (&&) with short-circuiting.

Evaluates left-to-right, jumping around subsequent operands when a false operand is encountered.

Parameters
bcTarget bytecode.
srcSource buffer.
lenSource length.
posIn/out byte position pointer.
Returns
1 on success, 0 on error.

Definition at line 4658 of file parser.c.

◆ emit_conditional()

int emit_conditional ( Bytecode * bc,
const char * src,
size_t len,
size_t * pos )
static

Parse and emit the ternary conditional operator.

Grammar (right-associative): logical_or ('?' conditional ':' conditional)?

Parameters
bcTarget bytecode.
srcSource buffer.
lenSource length.
posIn/out byte position pointer.
Returns
1 on success, 0 on error.

Definition at line 4800 of file parser.c.

◆ emit_equality()

int emit_equality ( Bytecode * bc,
const char * src,
size_t len,
size_t * pos )
static

Parse and emit equality/inequality expressions.

Grammar: relational (('==' | '!=') relational)*

Parameters
bcTarget bytecode.
srcSource buffer.
lenSource length.
posIn/out byte position pointer.
Returns
1 on success, 0 on error.

Definition at line 4619 of file parser.c.

◆ emit_expression()

int emit_expression ( Bytecode * bc,
const char * src,
size_t len,
size_t * pos )
static

Parse and emit a full expression using precedence climbing.

Delegates to emit_conditional which handles the highest-level precedence (ternary). This serves as the common entry for expression parsing at various grammar positions.

Parameters
bcTarget bytecode.
srcSource buffer.
lenSource length in bytes.
posIn/out byte position pointer.
Returns
1 on success, 0 on parse error.

Definition at line 4861 of file parser.c.

◆ emit_multiplicative()

int emit_multiplicative ( Bytecode * bc,
const char * src,
size_t len,
size_t * pos )
static

Parse and emit multiplicative expressions.

Grammar: unary (('' | '/' | '') unary)

Parameters
bcTarget bytecode.
srcSource buffer.
lenSource length.
posIn/out byte position pointer.
Returns
1 on success, 0 on error.

Definition at line 4462 of file parser.c.

◆ emit_or_expr()

int emit_or_expr ( Bytecode * bc,
const char * src,
size_t len,
size_t * pos )
static

Parse and emit logical OR (||) with short-circuiting.

Evaluates left-to-right; when a true operand is encountered, remaining operands are skipped and the expression yields true.

Parameters
bcTarget bytecode.
srcSource buffer.
lenSource length.
posIn/out byte position pointer.
Returns
1 on success, 0 on error.

Definition at line 4729 of file parser.c.

◆ emit_primary()

int emit_primary ( Bytecode * bc,
const char * src,
size_t len,
size_t * pos )
static

Parse and emit bytecode for primary expressions.

Handles literals, identifiers, parenthesized expressions, function literals, array/map literals, indexing, calls, member access, and related constructs.

Parameters
bcTarget bytecode under construction.
srcSource buffer.
lenSource length in bytes.
posIn/out byte position pointer; advanced past the parsed primary.
Returns
1 on success, 0 on parse error.

Definition at line 393 of file parser.c.

◆ emit_relational()

int emit_relational ( Bytecode * bc,
const char * src,
size_t len,
size_t * pos )
static

Parse and emit relational expressions.

Grammar: additive (('<' | '<=' | '>' | '>=') additive)*

Parameters
bcTarget bytecode.
srcSource buffer.
lenSource length.
posIn/out byte position pointer.
Returns
1 on success, 0 on error.

Definition at line 4563 of file parser.c.

◆ emit_unary()

int emit_unary ( Bytecode * bc,
const char * src,
size_t len,
size_t * pos )
static

Parse and emit unary expressions.

Supports logical not (!) and unary minus (-) with right associativity, falling back to primary expressions.

Parameters
bcTarget bytecode.
srcSource buffer.
lenSource length.
posIn/out byte position pointer.
Returns
1 on success, 0 on error.

Definition at line 4425 of file parser.c.

◆ env_truthy()

int env_truthy ( const char * name)
static

Interpret an environment variable as a boolean flag.

Recognizes common truthy forms: 1, true/TRUE, yes/YES, on/ON. Any other value (including unset) is considered false.

Parameters
nameEnvironment variable name (must not be NULL).
Returns
1 if the variable is set to a recognized truthy value, 0 otherwise.

Definition at line 81 of file parser.c.

◆ fun_debug_enabled()

int fun_debug_enabled ( void )
static

Determine whether parser/compiler debug tracing is enabled.

Debugging can be enabled by setting either FUN_TRACE or FUN_DEBUG to a truthy environment value (see env_truthy).

Returns
1 if debug is enabled, 0 otherwise.

Definition at line 102 of file parser.c.

◆ is_ns_alias()

int is_ns_alias ( const char * name)
static

Check whether an identifier is a registered namespace alias.

Parameters
nameIdentifier to test.
Returns
1 if name is a known alias, 0 otherwise.

Definition at line 248 of file parser.c.

◆ local_add()

int local_add ( const char * name)
static

Add a new local variable to the current function environment.

Parameters
nameLocal identifier to define.
Returns
The assigned local index, or -1 if no function env exists or limit exceeded.

Definition at line 366 of file parser.c.

◆ local_find()

int local_find ( const char * name)
static

Find the index of a local variable in the current function.

Parameters
nameLocal identifier to look up.
Returns
Zero-based local index, or -1 if not found or outside a function.

Definition at line 352 of file parser.c.

◆ name_in_outer_envs()

int name_in_outer_envs ( const char * name)
static

Check whether a local name exists in any outer function environment.

Used to enforce no-capture semantics for nested functions.

Parameters
nameLocal identifier to search for.
Returns
1 if present in any outer environment, 0 otherwise.

Definition at line 323 of file parser.c.

◆ ns_aliases_reset()

void ns_aliases_reset ( void )
static

Reset and free all tracked namespace aliases.

Definition at line 186 of file parser.c.

◆ ns_aliases_scan()

void ns_aliases_scan ( const char * src,
size_t len )
static

Scan preprocessed source for namespace alias markers.

Looks for lines starting with "// __ns_alias__: <name>" and stores <name> so that member-style calls on that identifier are parsed as plain calls (no implicit receiver).

Parameters
srcPreprocessed source buffer.
lenLength of src in bytes.

Definition at line 204 of file parser.c.

◆ parse_block()

void parse_block ( Bytecode * bc,
const char * src,
size_t len,
size_t * pos,
int current_indent )
static

Parse a block of statements at a given indentation level.

Continues parsing lines while their indentation is >= current_indent. On dedent, returns control to the caller so upstream constructs (e.g., if/while) can close. Inserts OP_LINE markers to improve runtime diagnostics.

Parameters
bcTarget bytecode.
srcSource buffer.
lenSource length.
posIn/out byte position pointer.
current_indentIndentation level (spaces) of the enclosing block.

Definition at line 5930 of file parser.c.

◆ parse_file_to_bytecode()

Bytecode * parse_file_to_bytecode ( const char * path)

Parse a .fun source file and return compiled bytecode.

Parse a .fun source file and compile it into a bytecode chunk.

Reads the file, preprocesses includes (tracking original file paths), resets the global error state, and compiles to Bytecode while attaching source metadata (name, source_file).

Parameters
pathFilesystem path to the source file.
Returns
Bytecode pointer on success; NULL on I/O or parse error.

Definition at line 7526 of file parser.c.

◆ parse_simple_statement()

void parse_simple_statement ( Bytecode * bc,
const char * src,
size_t len,
size_t * pos )
static

Parse a single statement on the current line and emit bytecode.

Handles assignments, function calls, control flow starters, print/debug statements and other simple constructs that fit on one logical line.

Parameters
bcTarget bytecode.
srcSource buffer.
lenSource length.
posIn/out byte position pointer at start of the statement line.

Definition at line 5065 of file parser.c.

◆ parse_string_to_bytecode()

Bytecode * parse_string_to_bytecode ( const char * source)

Parse a source string and return compiled bytecode.

Parse source from a provided string buffer (REPL/tests helper).

Suitable for REPL or tests. Performs include preprocessing with no base path, compiles, and attaches generic source metadata.

Parameters
sourceNUL-terminated source code string.
Returns
Bytecode pointer on success; NULL on parse error.

Definition at line 7711 of file parser.c.

◆ parser_fail()

void parser_fail ( size_t pos,
const char * fmt,
... )
static

Record a parser/compiler error at a given source position.

Formats an error message into the parser's global error buffer and stores the offending byte position. Line and column are derived later on demand.

Parameters
posByte offset in the current (preprocessed) source.
fmtprintf-style format string for the message.
...Arguments matching fmt.

Definition at line 139 of file parser.c.

◆ parser_last_error()

int parser_last_error ( char * msgBuf,
unsigned long msgCap,
int * outLine,
int * outCol )

Retrieve the last parser/compiler error information, if any.

Retrieve information about the last parser error, if any.

Copies the error message into msgBuf (truncated to msgCap-1), and returns the one-based line and column where available. If no error is pending, returns 0 and leaves outputs unchanged.

Parameters
msgBufDestination buffer for the error message (may be NULL).
msgCapCapacity of msgBuf in bytes.
outLineOptional out param for one-based line number.
outColOptional out param for one-based column number.
Returns
1 if an error was available and copied, 0 otherwise.

Definition at line 7767 of file parser.c.

◆ preprocess_includes_with_path()

char * preprocess_includes_with_path ( const char * src,
const char * current_path )
extern

Preprocess includes with a known file path to improve span markers.

Definition at line 973 of file parser_utils.c.

◆ read_line_start()

int read_line_start ( const char * src,
size_t len,
size_t * pos,
int * out_indent )
static

Read the start of a logical line and compute indentation.

Consumes blank lines and comment-only lines. Tabs are forbidden for indentation; only spaces are allowed, counted in units of 2.

Parameters
srcSource buffer.
lenSource length.
posIn/out byte position pointer; advanced to first non-space.
out_indentReceives the number of leading spaces on the line.
Returns
1 if a non-empty logical line was found, 0 if end reached.

Read the start of a logical line and compute indentation.

Consumes blank lines and comment-only lines. Tabs are forbidden for indentation; only spaces are allowed, counted in units of 2.

Parameters
srcSource buffer.
lenSource length.
posIn/out byte position pointer; advanced to first non-space.
out_indentReceives the number of leading spaces on the line.
Returns
1 if a non-empty logical line was found, 0 if end reached.

Definition at line 4972 of file parser.c.

◆ skip_to_eol()

void skip_to_eol ( const char * src,
size_t len,
size_t * pos )
static

Advance position to the end of the current line, validating tail.

Skips spaces and inline/block comments until CR/LF/CRLF or end-of-input. Reports an error if trailing non-space/comment characters are found.

Parameters
srcSource buffer.
lenSource length.
posIn/out byte position pointer; set to first char of next line.

Definition at line 4884 of file parser.c.

◆ sym_find()

int sym_find ( const char * name)
static

Find a global symbol index by name.

Parameters
nameSymbol name.
Returns
Index in the global table, or -1 if not found.

Definition at line 272 of file parser.c.

◆ sym_index()

int sym_index ( const char * name)
static

Get or create a global symbol index for a name.

Ensures the symbol exists in the global table, creating a new entry with default metadata when absent.

Parameters
nameSymbol name.
Returns
Index of the symbol (>=0). Returns 0 after reporting an error if the table is full.

Definition at line 289 of file parser.c.

Variable Documentation

◆ count

int count

Definition at line 263 of file parser.c.

◆ [struct]

struct { ... } G

◆ g_current_source_path

const char* g_current_source_path = NULL
static

Definition at line 61 of file parser.c.

◆ g_err_col

int g_err_col = 0
static

Definition at line 66 of file parser.c.

◆ g_err_line

int g_err_line = 0
static

Definition at line 65 of file parser.c.

◆ g_err_msg

char g_err_msg[256]
static

Definition at line 64 of file parser.c.

◆ g_err_pos

size_t g_err_pos = 0
static

Definition at line 63 of file parser.c.

◆ g_func_env_depth

int g_func_env_depth = 0
static

Definition at line 313 of file parser.c.

◆ g_func_env_stack

LocalEnv* g_func_env_stack[64]
static

Definition at line 312 of file parser.c.

◆ g_has_error

int g_has_error = 0
static

Definition at line 62 of file parser.c.

◆ g_locals

LocalEnv* g_locals = NULL
static

Definition at line 309 of file parser.c.

◆ g_loop_ctx

LoopCtx* g_loop_ctx = NULL
static

Definition at line 344 of file parser.c.

◆ g_ns_alias_count

int g_ns_alias_count = 0
static

Definition at line 181 of file parser.c.

◆ g_ns_aliases

char* g_ns_aliases[64]
static

Definition at line 180 of file parser.c.

◆ g_temp_counter

int g_temp_counter = 0
static

Definition at line 69 of file parser.c.

◆ is_class

int is_class[MAX_GLOBALS]

Definition at line 262 of file parser.c.

◆ names

char* names[MAX_GLOBALS]

Definition at line 260 of file parser.c.

◆ types

int types[MAX_GLOBALS]

Definition at line 261 of file parser.c.