diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..b054de5
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,12 @@
+AC_INIT([vinum], [1.0])
+AM_INIT_AUTOMAKE([foreign -Wall -Werror])
+
+CFLAGS=""
+AC_PROG_CC
+
+AC_PROG_YACC
+AC_PROG_LEX(noyywrap)
+
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_FILES([Makefile src/Makefile])
+AC_OUTPUT
diff --git a/meson.build b/meson.build
index fd4e0d7..8c95470 100644
--- a/meson.build
+++ b/meson.build
@@ -1,4 +1,4 @@
-project('vinum', 'c', meson_version: '>=1.1',
+project('vinum', 'c', meson_version: '>=0.61.2',
default_options : [
'werror=true',
'warning_level=2',
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..cf58a8d
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,23 @@
+AM_CFLAGS = -Wall -Wextra -Werror -g
+AM_YFLAGS = -d
+
+bin_PROGRAMS = vinumc sweet_vinumc
+
+BUILT_SOURCES = dry_bison.h sweet_bison.h
+
+vinumc_SOURCES = \
+ ast.c \
+ ast_bison_helpers.c \
+ dry_bison.y \
+ dry_flex.l \
+ eval.c \
+ vinumc.c
+
+sweet_vinumc_SOURCES = \
+ sweet_bison.y \
+ sweet_flex.l \
+ sweet_vinumc.c
+
+CLEANFILES = \
+ sweet_flex.c \
+ sweet_bison.c
diff --git a/src/config.log b/src/config.log
new file mode 100644
index 0000000..94db48a
--- /dev/null
+++ b/src/config.log
@@ -0,0 +1,236 @@
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by vinum configure 1.0, which was
+generated by GNU Autoconf 2.71. Invocation command line was
+
+ $ ../configure
+
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = compiuter
+uname -m = x86_64
+uname -r = 5.15.167.4-microsoft-standard-WSL2
+uname -s = Linux
+uname -v = #1 SMP Tue Nov 5 00:21:55 UTC 2024
+
+/usr/bin/uname -p = x86_64
+/bin/uname -X = unknown
+
+/bin/arch = x86_64
+/usr/bin/arch -k = unknown
+/usr/convex/getsysinfo = unknown
+/usr/bin/hostinfo = unknown
+/bin/machine = unknown
+/usr/bin/oslevel = unknown
+/bin/universe = unknown
+
+PATH: /usr/local/sbin/
+PATH: /usr/local/bin/
+PATH: /usr/sbin/
+PATH: /usr/bin/
+PATH: /sbin/
+PATH: /bin/
+PATH: /usr/games/
+PATH: /usr/local/games/
+PATH: /usr/lib/wsl/lib/
+PATH: /mnt/c/Windows/system32/
+PATH: /mnt/c/Windows/
+PATH: /mnt/c/Windows/System32/Wbem/
+PATH: /mnt/c/Windows/System32/WindowsPowerShell/v1.0/
+PATH: /mnt/c/Windows/System32/OpenSSH/
+PATH: /mnt/c/Program Files/dotnet/
+PATH: /mnt/c/Program Files/NVIDIA Corporation/NVIDIA NvDLISR/
+PATH: /mnt/c/WINDOWS/system32/
+PATH: /mnt/c/WINDOWS/
+PATH: /mnt/c/WINDOWS/System32/Wbem/
+PATH: /mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/
+PATH: /mnt/c/WINDOWS/System32/OpenSSH/
+PATH: /mnt/c/Program Files/Git/cmd/
+PATH: /mnt/c/ProgramData/chocolatey/bin/
+PATH: /mnt/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common/
+PATH: /Docker/host/bin/
+PATH: /mnt/c/Program Files/Go/bin/
+PATH: /mnt/c/Users/arthu/.cargo/bin/
+PATH: /mnt/c/Users/arthu/AppData/Local/Microsoft/WindowsApps/
+PATH: /mnt/c/Users/arthu/AppData/Local/Programs/Microsoft VS Code/bin/
+PATH: /mnt/c/Program Files/zstd-v1.5.6-win64/
+PATH: /mnt/c/Users/arthu/go/bin/
+PATH: /mnt/c/users/arthu/appdata/local/packages/pythonsoftwarefoundation.python.3.12_qbz5n2kfra8p0/localcache/local-packages/python312/scripts/
+PATH: /mnt/c/users/arthu/.local/bin/
+PATH: /mnt/c/Users/arthu/AppData/Roaming/nvm/
+PATH: /mnt/c/Program Files/nodejs/
+PATH: /home/vergacas/.local/bin/
+PATH: /usr/local/go/bin/
+PATH: /home/vergacas/.local/bin/
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+configure:2154: looking for aux files: compile missing install-sh
+configure:2167: trying ../
+configure:2196: ../compile found
+configure:2196: ../missing found
+configure:2178: ../install-sh found
+configure:2325: checking for a BSD-compatible install
+configure:2398: result: /usr/bin/install -c
+configure:2409: checking whether build environment is sane
+configure:2464: result: yes
+configure:2623: checking for a race-free mkdir -p
+configure:2667: result: /usr/bin/mkdir -p
+configure:2674: checking for gawk
+configure:2695: found /usr/bin/gawk
+configure:2706: result: gawk
+configure:2717: checking whether make sets $(MAKE)
+configure:2740: result: yes
+configure:2770: checking whether make supports nested variables
+configure:2788: result: yes
+configure:2805: error: source directory already configured; run "make distclean" there first
+
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+
+ac_cv_env_CC_set=
+ac_cv_env_CC_value=
+ac_cv_env_CFLAGS_set=
+ac_cv_env_CFLAGS_value=
+ac_cv_env_CPPFLAGS_set=
+ac_cv_env_CPPFLAGS_value=
+ac_cv_env_LDFLAGS_set=
+ac_cv_env_LDFLAGS_value=
+ac_cv_env_LIBS_set=
+ac_cv_env_LIBS_value=
+ac_cv_env_YACC_set=
+ac_cv_env_YACC_value=
+ac_cv_env_YFLAGS_set=
+ac_cv_env_YFLAGS_value=
+ac_cv_env_build_alias_set=
+ac_cv_env_build_alias_value=
+ac_cv_env_host_alias_set=
+ac_cv_env_host_alias_value=
+ac_cv_env_target_alias_set=
+ac_cv_env_target_alias_value=
+ac_cv_path_install='/usr/bin/install -c'
+ac_cv_path_mkdir=/usr/bin/mkdir
+ac_cv_prog_AWK=gawk
+ac_cv_prog_make_make_set=yes
+am_cv_make_support_nested_variables=yes
+
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+
+ACLOCAL=''
+AMDEPBACKSLASH=''
+AMDEP_FALSE=''
+AMDEP_TRUE=''
+AMTAR=''
+AM_BACKSLASH='\'
+AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+AM_DEFAULT_VERBOSITY='1'
+AM_V='$(V)'
+AUTOCONF=''
+AUTOHEADER=''
+AUTOMAKE=''
+AWK='gawk'
+CC=''
+CCDEPMODE=''
+CFLAGS=''
+CPPFLAGS=''
+CSCOPE=''
+CTAGS=''
+CYGPATH_W=''
+DEFS=''
+DEPDIR=''
+ECHO_C=''
+ECHO_N='-n'
+ECHO_T=''
+ETAGS=''
+EXEEXT=''
+INSTALL_DATA='${INSTALL} -m 644'
+INSTALL_PROGRAM='${INSTALL}'
+INSTALL_SCRIPT='${INSTALL}'
+INSTALL_STRIP_PROGRAM='$(install_sh) -c -s'
+LDFLAGS=''
+LEX=''
+LEXLIB=''
+LEX_OUTPUT_ROOT=''
+LIBOBJS=''
+LIBS=''
+LTLIBOBJS=''
+MAKEINFO=''
+MKDIR_P='/usr/bin/mkdir -p'
+OBJEXT=''
+PACKAGE=''
+PACKAGE_BUGREPORT=''
+PACKAGE_NAME='vinum'
+PACKAGE_STRING='vinum 1.0'
+PACKAGE_TARNAME='vinum'
+PACKAGE_URL=''
+PACKAGE_VERSION='1.0'
+PATH_SEPARATOR=':'
+SET_MAKE=''
+SHELL='/bin/bash'
+STRIP=''
+VERSION=''
+YACC=''
+YFLAGS=''
+ac_ct_CC=''
+am__EXEEXT_FALSE=''
+am__EXEEXT_TRUE=''
+am__fastdepCC_FALSE=''
+am__fastdepCC_TRUE=''
+am__include=''
+am__isrc=' -I$(srcdir)'
+am__leading_dot='.'
+am__nodep=''
+am__quote=''
+am__tar=''
+am__untar=''
+bindir='${exec_prefix}/bin'
+build_alias=''
+datadir='${datarootdir}'
+datarootdir='${prefix}/share'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+dvidir='${docdir}'
+exec_prefix='NONE'
+host_alias=''
+htmldir='${docdir}'
+includedir='${prefix}/include'
+infodir='${datarootdir}/info'
+install_sh='${SHELL} /home/vergacas/ic/vinum/install-sh'
+libdir='${exec_prefix}/lib'
+libexecdir='${exec_prefix}/libexec'
+localedir='${datarootdir}/locale'
+localstatedir='${prefix}/var'
+mandir='${datarootdir}/man'
+mkdir_p=''
+oldincludedir='/usr/include'
+pdfdir='${docdir}'
+prefix='NONE'
+program_transform_name='s,x,x,'
+psdir='${docdir}'
+runstatedir='${localstatedir}/run'
+sbindir='${exec_prefix}/sbin'
+sharedstatedir='${prefix}/com'
+sysconfdir='${prefix}/etc'
+target_alias=''
+
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+
+/* confdefs.h */
+#define PACKAGE_NAME "vinum"
+#define PACKAGE_TARNAME "vinum"
+#define PACKAGE_VERSION "1.0"
+#define PACKAGE_STRING "vinum 1.0"
+#define PACKAGE_BUGREPORT ""
+#define PACKAGE_URL ""
+
+configure: exit 1
diff --git a/src/sweet_bison.h b/src/sweet_bison.h
new file mode 100644
index 0000000..8eb1c78
--- /dev/null
+++ b/src/sweet_bison.h
@@ -0,0 +1,93 @@
+/* A Bison parser, made by GNU Bison 3.8.2. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+ especially those whose name start with YY_ or yy_. They are
+ private implementation details that can be changed or removed. */
+
+#ifndef YY_YY_SWEET_BISON_H_INCLUDED
+# define YY_YY_SWEET_BISON_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token kinds. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ YYEMPTY = -2,
+ YYEOF = 0, /* "end of file" */
+ YYerror = 256, /* error */
+ YYUNDEF = 257, /* "invalid token" */
+ NAME = 258, /* NAME */
+ CONTENT = 259 /* CONTENT */
+ };
+ typedef enum yytokentype yytoken_kind_t;
+#endif
+/* Token kinds. */
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYerror 256
+#define YYUNDEF 257
+#define NAME 258
+#define CONTENT 259
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+union YYSTYPE
+{
+#line 21 "sweet_bison.y"
+
+ char* str;
+
+#line 79 "sweet_bison.h"
+
+};
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE yylval;
+
+
+int yyparse (void);
+
+
+#endif /* !YY_YY_SWEET_BISON_H_INCLUDED */
diff --git a/src/sweet_bison.y b/src/sweet_bison.y
new file mode 100644
index 0000000..0cb93a1
--- /dev/null
+++ b/src/sweet_bison.y
@@ -0,0 +1,194 @@
+%{
+#include
+#include
+#include
+
+#include "sweet_vinumc.h"
+
+// Forward declaration
+int yylex();
+
+// Utility function declarations
+char* concat(const char* a, const char* b);
+char* format_block(const char* name, const char* content);
+char* format_call(const char* outer, const char* inner);
+char* put_in_chain(const char* inner_block, const char* call_chain);
+
+// Output file pointer
+extern FILE* output_file;
+%}
+
+%union {
+ char* str;
+}
+
+%token NAME CONTENT
+%type program block call final_
+
+%%
+
+// Entry point of the parser; prints the fully transpiled result
+final_:
+ program {
+ $$ = strdup($1);
+ free($1);
+ if (output_file) {
+ fprintf(output_file, "%s", $$);
+ }
+ }
+;
+
+// Program: sequence of blocks or empty
+program:
+ /* empty */ { $$ = strdup(""); }
+ | program block {
+ $$ = concat($1, $2);
+ free($1);
+ free($2);
+ }
+;
+
+// Block constructs
+block:
+ // Parenthesized block
+ '(' program ')' {
+ size_t len = strlen($2) + 3;
+ $$ = malloc(len);
+ snprintf($$, len, "(%s)", $2);
+ free($2);
+ }
+ // Parenthesized block with call chain
+ | '(' program ')' '.' NAME call {
+ char* first_block = format_block($5, $2);
+ char* chained_block = put_in_chain(first_block, $6);
+ $$ = format_block(chained_block, "");
+ free($5);
+ free($2);
+ free($6);
+ }
+ // Parenthesized block with single call
+ | '(' program ')' call {
+ $$ = format_block($4, $2);
+ free($4);
+ free($2);
+ }
+ // Call without arguments block
+ | call {
+ $$ = format_block($1, "");
+ free($1);
+ }
+ // Raw content
+ | CONTENT {
+ $$ = strdup($1);
+ free($1);
+ }
+;
+
+// Chained function calls
+call:
+ '.' NAME {
+ $$ = strdup($2);
+ free($2);
+ }
+ | call '.' NAME {
+ $$ = format_call($3, $1);
+ free($1);
+ free($3);
+ }
+;
+
+%%
+
+/**
+ * Concatenates two strings. If either string is empty, returns a copy of the other.
+ *
+ * @param a First string
+ * @param b Second string
+ * @return Concatenated result
+ */
+char* concat(const char* a, const char* b) {
+ if (strlen(a) == 0) return strdup(b);
+ if (strlen(b) == 0) return strdup(a);
+
+ size_t len = strlen(a) + strlen(b) + 2; // +1 for NULL and extra safety
+ char* result = malloc(len);
+ snprintf(result, len, "%s%s", a, b);
+ return result;
+}
+
+/**
+ * Formats a function block in the dry flavor: [name content] or [name] if content is empty.
+ *
+ * @param name Function name
+ * @param content Block content
+ * @return Formatted dry-style block
+ */
+char* format_block(const char* name, const char* content) {
+ size_t len = strlen(name) + strlen(content) + 4; // [], space and NULL
+ char* result = malloc(len);
+
+ if (strlen(content) > 0)
+ snprintf(result, len, "[%s %s]", name, content);
+ else
+ snprintf(result, len, "[%s]", name);
+
+ return result;
+}
+
+/**
+ * Formats a function call inside another: returns a string like `outer [inner]`.
+ *
+ * @param outer Outer function name
+ * @param inner Inner block
+ * @return Nested block string
+ */
+char* format_call(const char* outer, const char* inner) {
+ size_t len = strlen(outer) + strlen(inner) + 5; // '[', ' ', ']', NULL
+ char* result = malloc(len);
+ snprintf(result, len, "%s [%s]", outer, inner);
+ return result;
+}
+
+/**
+ * Inserts an inner block into the last nested position of a call chain.
+ *
+ * For example:
+ * call_chain = "bar [baz [qux]]"
+ * inner_block = "[foo content]"
+ * result = "bar [baz [qux [foo content]]]"
+ *
+ * @param inner_block The block to be inserted (e.g., "[foo content]")
+ * @param call_chain The chain of nested calls (e.g., "bar [baz [qux]]")
+ * @return A newly allocated string with inner_block inserted at the correct position.
+ */
+char* put_in_chain(const char* inner_block, const char* call_chain) {
+ if (!call_chain || strlen(call_chain) == 0) {
+ return strdup(inner_block);
+ }
+
+ size_t call_len = strlen(call_chain);
+ size_t inner_len = strlen(inner_block);
+
+ // Find the position where the final ']' sequence starts
+ ssize_t i = call_len - 1;
+ while (i >= 0 && call_chain[i] == ']') {
+ i--;
+ }
+ i++;
+
+ // Split the call_chain into prefix and suffix
+ char* prefix = strndup(call_chain, i);
+ char* suffix = strdup(&call_chain[i]);
+
+ size_t result_len = strlen(prefix) + inner_len + strlen(suffix) + 2; // +1 for space +1 for '\0'
+ char* result = malloc(result_len);
+
+ // Format the final string
+ snprintf(result, result_len, "%s %s%s", prefix, inner_block, suffix);
+
+ // Clean up temporary strings
+ free(prefix);
+ free(suffix);
+
+ return result;
+}
diff --git a/src/sweet_flex.l b/src/sweet_flex.l
new file mode 100644
index 0000000..370f32c
--- /dev/null
+++ b/src/sweet_flex.l
@@ -0,0 +1,57 @@
+%option noyywrap nodefault yylineno
+
+%{
+#include
+#include
+#include
+#include "sweet_bison.h"
+#include "sweet_vinumc.h"
+
+#define YY_NO_INPUT
+%}
+
+/* Define custom lexer state */
+%s AFTER_DOT
+
+%%
+
+"(" { return '('; }
+")" { return ')'; }
+
+"."[a-zA-Z_] {
+/* Dot followed by identifier: return dot and leave identifier for next token */
+ unput(yytext[1]);
+/* Switch to AFTER_DOT mode */
+ BEGIN(AFTER_DOT);
+ return '.';
+}
+
+[a-zA-Z_][a-zA-Z0-9_]* {
+/* In AFTER_DOT state: match NAME */
+ yylval.str = strdup(yytext);
+ BEGIN(INITIAL); // back to default state
+ return NAME;
+}
+
+. {
+/* In AFTER_DOT state: fallback to CONTENT and revert state */
+ // Not a valid NAME after dot, treat it as content
+ char* s = malloc(strlen(yytext) + 2);
+ snprintf(s, strlen(yytext) + 2, "%s", yytext);
+ yylval.str = s;
+ BEGIN(INITIAL);
+ return CONTENT;
+}
+
+[ \t\n]+ {
+/* Whitespace or newline: CONTENT */
+ yylval.str = strdup(yytext);
+ return CONTENT;
+}
+
+. {
+/* Any other character: also CONTENT */
+ yylval.str = strdup(yytext);
+ return CONTENT;
+}
+%%
diff --git a/src/sweet_vinumc.c b/src/sweet_vinumc.c
new file mode 100644
index 0000000..c906126
--- /dev/null
+++ b/src/sweet_vinumc.c
@@ -0,0 +1,105 @@
+#include
+#include
+#include
+#include
+
+#include "sweet_vinumc.h"
+
+// External lexer input file pointer
+extern FILE *yyin;
+
+// Output file to write the dry result
+FILE *output_file = NULL;
+
+/**
+ * Error reporting function for the Bison parser.
+ *
+ * Accepts a printf-style format and optional arguments.
+ *
+ * @param s Format string
+ */
+void yyerror(char *s, ...) {
+ va_list ap;
+ va_start(ap, s);
+
+ fprintf(stderr, "[ERROR]: ");
+ vfprintf(stderr, s, ap);
+ fprintf(stderr, "\n");
+
+ va_end(ap);
+}
+
+/**
+ * Creates a new string with the same base as the input filename,
+ * but with the suffix "_dry.vin".
+ *
+ * For example: input "foo.vin" → output "foo_dry.vin"
+ *
+ * @param filename Original input filename
+ * @return Newly allocated output filename with "_dry.vin" suffix
+ */
+char* append_dry_suffix(const char* filename) {
+ const char* dot = strrchr(filename, '.');
+ size_t base_len = dot ? (size_t)(dot - filename) : strlen(filename);
+ const char* suffix = "_dry.vin";
+ size_t result_len = base_len + strlen(suffix) + 1;
+
+ char* result = malloc(result_len);
+ if (!result) {
+ fprintf(stderr, "Memory allocation error.\n");
+ exit(1);
+ }
+
+ strncpy(result, filename, base_len);
+ result[base_len] = '\0';
+ strcat(result, suffix);
+ return result;
+}
+
+/**
+ * Entry point of the transpiler.
+ *
+ * Opens the sweet-style source file, parses it using Flex/Bison,
+ * and writes the dry-style output to a new file.
+ *
+ * @param argc Number of command-line arguments
+ * @param argv Array of command-line arguments
+ * @return Exit code (0 on success, 1 on error)
+ */
+int main(int argc, char *argv[]) {
+ // Require input file argument
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s \n", argv[0]);
+ return 1;
+ }
+
+ const char* input_filename = argv[1];
+ FILE* input = fopen(input_filename, "r");
+ if (!input) {
+ perror("Error opening input file");
+ return 1;
+ }
+
+ // Set Flex to read from input file
+ yyin = input;
+
+ // Generate output filename
+ char* output_filename = append_dry_suffix(input_filename);
+ output_file = fopen(output_filename, "w");
+ if (!output_file) {
+ perror("Error creating output file");
+ fclose(input);
+ free(output_filename);
+ return 1;
+ }
+
+ // Parse input file
+ int status = yyparse();
+
+ // Cleanup
+ fclose(input);
+ fclose(output_file);
+ free(output_filename);
+
+ return status;
+}
diff --git a/src/sweet_vinumc.h b/src/sweet_vinumc.h
new file mode 100644
index 0000000..1e7648b
--- /dev/null
+++ b/src/sweet_vinumc.h
@@ -0,0 +1,7 @@
+#ifndef __SWEET_VINUMC_H__
+#define __SWEET_VINUMC_H__
+
+void yyerror(char *s, ...);
+int yyparse();
+
+#endif // __SWEET_VINUMC_H__
diff --git a/src/test_sweet.vin b/src/test_sweet.vin
new file mode 100644
index 0000000..fa6b116
--- /dev/null
+++ b/src/test_sweet.vin
@@ -0,0 +1,14 @@
+(foo).bar
+o homem é a ponte entre o animal e o além-do-homem.
+(baz (qux).quux).foo
+(penso logo existo)
+(a dúvida é (meio) (da).parte jornada).bar
+.foo
+a única sabedoria é saber que nada sei .bar (baz).qux
+.init (a).step (b) (c (d) e).final (f (g).h (i)).end.
+(((Só sei que nada sei).foo).bar).baz
+(Só sei que nada sei).foo.bar.baz
+(.foo [qux]).bar
+(((O homem é a medida de todas as coisas).foo).bar .baz).qux
+.a.b.c.d.e.f
+(a).b.c.
\ No newline at end of file
diff --git a/src/test_sweet_dry.vin b/src/test_sweet_dry.vin
new file mode 100644
index 0000000..ad21404
--- /dev/null
+++ b/src/test_sweet_dry.vin
@@ -0,0 +1,14 @@
+[bar foo]
+o homem é a ponte entre o animal e o além-do-homem.
+[foo baz [quux qux]]
+(penso logo existo)
+[bar a dúvida é (meio) [parte da] jornada]
+[foo]
+a única sabedoria é saber que nada sei [bar] [qux baz]
+[init] [step a] (b) [final c (d) e] [end f [h g] (i)].
+[baz [bar [foo Só sei que nada sei]]]
+[baz [bar [foo Só sei que nada sei]]]
+[bar [foo] [qux]]
+[qux [bar [foo O homem é a medida de todas as coisas]] [baz]]
+[f [e [d [c [b [a]]]]]]
+[c [b a]].
\ No newline at end of file
diff --git a/src/ylwrap10791/y.tab.c b/src/ylwrap10791/y.tab.c
new file mode 100644
index 0000000..c02f17a
--- /dev/null
+++ b/src/ylwrap10791/y.tab.c
@@ -0,0 +1,1475 @@
+/* A Bison parser, made by GNU Bison 3.8.2. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+ especially those whose name start with YY_ or yy_. They are
+ private implementation details that can be changed or removed. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output, and Bison version. */
+#define YYBISON 30802
+
+/* Bison version string. */
+#define YYBISON_VERSION "3.8.2"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+
+
+
+/* First part of user prologue. */
+#line 1 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+
+#include
+#include
+#include
+
+#include "sweet_vinumc.h"
+
+int yylex();
+
+char *include_content(char *content, char *block){
+ int block_size = strlen(block);
+ int content_size = strlen(content);
+ int len = block_size + content_size + 2;
+ char *complete_block = malloc(sizeof(char) * (len));
+ int pos;
+
+ for(pos = block_size; pos >= 0; pos--)
+ if(block[pos-1] != ']') break;
+
+ printf("\npos: %d\n", pos);
+
+ int i = 0;
+ for(int new_i = 0; new_i < len; new_i++){
+ if(new_i == pos){
+ complete_block[new_i] = ' ';
+ new_i++;
+
+ for(int j = 0; j <= content_size; j++)
+ complete_block[new_i+j] = content[j];
+
+ new_i += content_size;
+ }
+ complete_block[new_i] = block[i];
+ i++;
+ }
+
+ return complete_block;
+}
+
+
+#line 112 "y.tab.c"
+
+# ifndef YY_CAST
+# ifdef __cplusplus
+# define YY_CAST(Type, Val) static_cast (Val)
+# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val)
+# else
+# define YY_CAST(Type, Val) ((Type) (Val))
+# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
+# endif
+# endif
+# ifndef YY_NULLPTR
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# else
+# define YY_NULLPTR ((void*)0)
+# endif
+# endif
+
+/* Use api.header.include to #include this header
+ instead of duplicating it here. */
+#ifndef YY_YY_Y_TAB_H_INCLUDED
+# define YY_YY_Y_TAB_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token kinds. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ YYEMPTY = -2,
+ YYEOF = 0, /* "end of file" */
+ YYerror = 256, /* error */
+ YYUNDEF = 257, /* "invalid token" */
+ CONTENT = 258, /* CONTENT */
+ NAME = 259 /* NAME */
+ };
+ typedef enum yytokentype yytoken_kind_t;
+#endif
+/* Token kinds. */
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYerror 256
+#define YYUNDEF 257
+#define CONTENT 258
+#define NAME 259
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+union YYSTYPE
+{
+#line 42 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+
+ char* str;
+
+#line 177 "y.tab.c"
+
+};
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE yylval;
+
+
+int yyparse (void);
+
+
+#endif /* !YY_YY_Y_TAB_H_INCLUDED */
+/* Symbol kind. */
+enum yysymbol_kind_t
+{
+ YYSYMBOL_YYEMPTY = -2,
+ YYSYMBOL_YYEOF = 0, /* "end of file" */
+ YYSYMBOL_YYerror = 1, /* error */
+ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */
+ YYSYMBOL_CONTENT = 3, /* CONTENT */
+ YYSYMBOL_NAME = 4, /* NAME */
+ YYSYMBOL_5_ = 5, /* '(' */
+ YYSYMBOL_6_ = 6, /* ')' */
+ YYSYMBOL_7_ = 7, /* '.' */
+ YYSYMBOL_YYACCEPT = 8, /* $accept */
+ YYSYMBOL_program = 9, /* program */
+ YYSYMBOL_block = 10, /* block */
+ YYSYMBOL_call = 11, /* call */
+ YYSYMBOL_content = 12, /* content */
+ YYSYMBOL_name = 13 /* name */
+};
+typedef enum yysymbol_kind_t yysymbol_kind_t;
+
+
+
+
+#ifdef short
+# undef short
+#endif
+
+/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
+ and (if available) are included
+ so that the code can choose integer types of a good width. */
+
+#ifndef __PTRDIFF_MAX__
+# include /* INFRINGES ON USER NAME SPACE */
+# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+# include /* INFRINGES ON USER NAME SPACE */
+# define YY_STDINT_H
+# endif
+#endif
+
+/* Narrow types that promote to a signed type and that can represent a
+ signed or unsigned integer of at least N bits. In tables they can
+ save space and decrease cache pressure. Promoting to a signed type
+ helps avoid bugs in integer arithmetic. */
+
+#ifdef __INT_LEAST8_MAX__
+typedef __INT_LEAST8_TYPE__ yytype_int8;
+#elif defined YY_STDINT_H
+typedef int_least8_t yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef __INT_LEAST16_MAX__
+typedef __INT_LEAST16_TYPE__ yytype_int16;
+#elif defined YY_STDINT_H
+typedef int_least16_t yytype_int16;
+#else
+typedef short yytype_int16;
+#endif
+
+/* Work around bug in HP-UX 11.23, which defines these macros
+ incorrectly for preprocessor constants. This workaround can likely
+ be removed in 2023, as HPE has promised support for HP-UX 11.23
+ (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
+ . */
+#ifdef __hpux
+# undef UINT_LEAST8_MAX
+# undef UINT_LEAST16_MAX
+# define UINT_LEAST8_MAX 255
+# define UINT_LEAST16_MAX 65535
+#endif
+
+#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST8_TYPE__ yytype_uint8;
+#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
+ && UINT_LEAST8_MAX <= INT_MAX)
+typedef uint_least8_t yytype_uint8;
+#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
+typedef unsigned char yytype_uint8;
+#else
+typedef short yytype_uint8;
+#endif
+
+#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST16_TYPE__ yytype_uint16;
+#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
+ && UINT_LEAST16_MAX <= INT_MAX)
+typedef uint_least16_t yytype_uint16;
+#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
+typedef unsigned short yytype_uint16;
+#else
+typedef int yytype_uint16;
+#endif
+
+#ifndef YYPTRDIFF_T
+# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
+# define YYPTRDIFF_T __PTRDIFF_TYPE__
+# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
+# elif defined PTRDIFF_MAX
+# ifndef ptrdiff_t
+# include /* INFRINGES ON USER NAME SPACE */
+# endif
+# define YYPTRDIFF_T ptrdiff_t
+# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
+# else
+# define YYPTRDIFF_T long
+# define YYPTRDIFF_MAXIMUM LONG_MAX
+# endif
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+# include /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM \
+ YY_CAST (YYPTRDIFF_T, \
+ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \
+ ? YYPTRDIFF_MAXIMUM \
+ : YY_CAST (YYSIZE_T, -1)))
+
+#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
+
+
+/* Stored state numbers (used for stacks). */
+typedef yytype_int8 yy_state_t;
+
+/* State numbers in computations. */
+typedef int yy_state_fast_t;
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+
+#ifndef YY_ATTRIBUTE_PURE
+# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
+# else
+# define YY_ATTRIBUTE_PURE
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+# else
+# define YY_ATTRIBUTE_UNUSED
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YY_USE(E) ((void) (E))
+#else
+# define YY_USE(E) /* empty */
+#endif
+
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")
+# else
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# endif
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_USELESS_CAST_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
+# define YY_IGNORE_USELESS_CAST_END \
+ _Pragma ("GCC diagnostic pop")
+#endif
+#ifndef YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_END
+#endif
+
+
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
+#if !defined yyoverflow
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+# include /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* !defined yyoverflow */
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yy_state_t yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYPTRDIFF_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / YYSIZEOF (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYPTRDIFF_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 2
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 25
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 8
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 6
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 13
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 19
+
+/* YYMAXUTOK -- Last valid token kind. */
+#define YYMAXUTOK 259
+
+
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
+#define YYTRANSLATE(YYX) \
+ (0 <= (YYX) && (YYX) <= YYMAXUTOK \
+ ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \
+ : YYSYMBOL_YYUNDEF)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex. */
+static const yytype_int8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 5, 6, 2, 2, 2, 2, 7, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4
+};
+
+#if YYDEBUG
+/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_int8 yyrline[] =
+{
+ 0, 53, 53, 54, 65, 71, 74, 77, 93, 99,
+ 108, 115, 118, 124
+};
+#endif
+
+/** Accessing symbol of state STATE. */
+#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
+
+#if YYDEBUG || 0
+/* The user-facing name of the symbol whose (internal) number is
+ YYSYMBOL. No bounds checking. */
+static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
+
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "\"end of file\"", "error", "\"invalid token\"", "CONTENT", "NAME",
+ "'('", "')'", "'.'", "$accept", "program", "block", "call", "content",
+ "name", YY_NULLPTR
+};
+
+static const char *
+yysymbol_name (yysymbol_kind_t yysymbol)
+{
+ return yytname[yysymbol];
+}
+#endif
+
+#define YYPACT_NINF (-7)
+
+#define yypact_value_is_default(Yyn) \
+ ((Yyn) == YYPACT_NINF)
+
+#define YYTABLE_NINF (-1)
+
+#define yytable_value_is_error(Yyn) \
+ 0
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int8 yypact[] =
+{
+ -7, 2, -7, -7, -7, 12, -3, 12, 13, -7,
+ 0, 7, -7, 12, -3, -7, 14, -7, 13
+};
+
+/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_int8 yydefact[] =
+{
+ 2, 0, 1, 11, 13, 12, 0, 3, 5, 6,
+ 12, 0, 8, 7, 0, 10, 0, 9, 4
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] =
+{
+ -7, -7, 17, 8, 15, -6
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int8 yydefgoto[] =
+{
+ 0, 1, 13, 8, 9, 10
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_int8 yytable[] =
+{
+ 12, 4, 2, 3, 4, 3, 4, 5, 17, 6,
+ 3, 4, 5, 16, 6, 3, 4, 5, 7, 6,
+ 14, 6, 11, 0, 18, 15
+};
+
+static const yytype_int8 yycheck[] =
+{
+ 6, 4, 0, 3, 4, 3, 4, 5, 14, 7,
+ 3, 4, 5, 6, 7, 3, 4, 5, 1, 7,
+ 7, 7, 5, -1, 16, 10
+};
+
+/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
+ state STATE-NUM. */
+static const yytype_int8 yystos[] =
+{
+ 0, 9, 0, 3, 4, 5, 7, 10, 11, 12,
+ 13, 10, 13, 10, 7, 12, 6, 13, 11
+};
+
+/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
+static const yytype_int8 yyr1[] =
+{
+ 0, 8, 9, 9, 10, 10, 10, 10, 11, 11,
+ 12, 12, 12, 13
+};
+
+/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
+static const yytype_int8 yyr2[] =
+{
+ 0, 2, 0, 2, 4, 1, 1, 2, 2, 3,
+ 2, 1, 0, 1
+};
+
+
+enum { YYENOMEM = -2 };
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+#define YYNOMEM goto yyexhaustedlab
+
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+ do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
+
+/* Backward compatibility with an undocumented macro.
+ Use YYerror or YYUNDEF. */
+#define YYERRCODE YYUNDEF
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+
+
+
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Kind, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyo,
+ yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
+{
+ FILE *yyoutput = yyo;
+ YY_USE (yyoutput);
+ if (!yyvaluep)
+ return;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YY_USE (yykind);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
+
+static void
+yy_symbol_print (FILE *yyo,
+ yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep)
+{
+ YYFPRINTF (yyo, "%s %s (",
+ yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
+
+ yy_symbol_value_print (yyo, yykind, yyvaluep);
+ YYFPRINTF (yyo, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,
+ int yyrule)
+{
+ int yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr,
+ YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
+ &yyvsp[(yyi + 1) - (yynrhs)]);
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args) ((void) 0)
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg,
+ yysymbol_kind_t yykind, YYSTYPE *yyvaluep)
+{
+ YY_USE (yyvaluep);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YY_USE (yykind);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+/* Lookahead token kind. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int
+yyparse (void)
+{
+ yy_state_fast_t yystate = 0;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus = 0;
+
+ /* Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* Their size. */
+ YYPTRDIFF_T yystacksize = YYINITDEPTH;
+
+ /* The state stack: array, bottom, top. */
+ yy_state_t yyssa[YYINITDEPTH];
+ yy_state_t *yyss = yyssa;
+ yy_state_t *yyssp = yyss;
+
+ /* The semantic value stack: array, bottom, top. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp = yyvs;
+
+ int yyn;
+ /* The return value of yyparse. */
+ int yyresult;
+ /* Lookahead symbol kind. */
+ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ goto yysetstate;
+
+
+/*------------------------------------------------------------.
+| yynewstate -- push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+
+/*--------------------------------------------------------------------.
+| yysetstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
+ YY_IGNORE_USELESS_CAST_BEGIN
+ *yyssp = YY_CAST (yy_state_t, yystate);
+ YY_IGNORE_USELESS_CAST_END
+ YY_STACK_PRINT (yyss, yyssp);
+
+ if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ YYNOMEM;
+#else
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYPTRDIFF_T yysize = yyssp - yyss + 1;
+
+# if defined yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ yy_state_t *yyss1 = yyss;
+ YYSTYPE *yyvs1 = yyvs;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * YYSIZEOF (*yyssp),
+ &yyvs1, yysize * YYSIZEOF (*yyvsp),
+ &yystacksize);
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+# else /* defined YYSTACK_RELOCATE */
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ YYNOMEM;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yy_state_t *yyss1 = yyss;
+ union yyalloc *yyptr =
+ YY_CAST (union yyalloc *,
+ YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
+ if (! yyptr)
+ YYNOMEM;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+ YY_IGNORE_USELESS_CAST_BEGIN
+ YYDPRINTF ((stderr, "Stack size increased to %ld\n",
+ YY_CAST (long, yystacksize)));
+ YY_IGNORE_USELESS_CAST_END
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token\n"));
+ yychar = yylex ();
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = YYEOF;
+ yytoken = YYSYMBOL_YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else if (yychar == YYerror)
+ {
+ /* The scanner already issued an error message, process directly
+ to error recovery. But do not keep the error token as
+ lookahead, it is too special and may lead us to an endless
+ loop in error recovery. */
+ yychar = YYUNDEF;
+ yytoken = YYSYMBOL_YYerror;
+ goto yyerrlab1;
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2: /* program: %empty */
+#line 53 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+ { (yyval.str) = strdup(""); }
+#line 1166 "y.tab.c"
+ break;
+
+ case 3: /* program: program block */
+#line 54 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+ {
+ // Concatena as linhas do programa
+ size_t len = strlen((yyvsp[-1].str)) + strlen((yyvsp[0].str)) + 1;
+ (yyval.str) = malloc(len + 1);
+ snprintf((yyval.str), len + 1, "%s%s", (yyvsp[-1].str), (yyvsp[0].str));
+ free((yyvsp[-1].str));
+ free((yyvsp[0].str));
+ printf("\nprogram: %s", (yyval.str));
+ }
+#line 1180 "y.tab.c"
+ break;
+
+ case 4: /* block: '(' block ')' call */
+#line 65 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+ {
+ // Transforma blocos Sweet em Dry
+ (yyval.str) = include_content((yyvsp[-2].str), (yyvsp[0].str));
+ free((yyvsp[-2].str));
+ free((yyvsp[0].str));
+ }
+#line 1191 "y.tab.c"
+ break;
+
+ case 5: /* block: call */
+#line 71 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+ {
+ (yyval.str) = (yyvsp[0].str);
+ }
+#line 1199 "y.tab.c"
+ break;
+
+ case 6: /* block: content */
+#line 74 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+ {
+ (yyval.str) = (yyvsp[0].str);
+ }
+#line 1207 "y.tab.c"
+ break;
+
+ case 7: /* block: block block */
+#line 77 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+ {
+ size_t len = strlen((yyvsp[-1].str)) + strlen((yyvsp[0].str)) + 1;
+ (yyval.str) = malloc(len);
+ snprintf((yyval.str), len, "%s%s", (yyvsp[-1].str), (yyvsp[0].str));
+ free((yyvsp[-1].str));
+ free((yyvsp[0].str));
+ }
+#line 1219 "y.tab.c"
+ break;
+
+ case 8: /* call: '.' name */
+#line 93 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+ {
+ size_t len = strlen((yyvsp[0].str)) + 3; // "[name]"
+ (yyval.str) = malloc(len);
+ snprintf((yyval.str), len, "[%s]", (yyvsp[0].str));
+ free((yyvsp[0].str));
+ }
+#line 1230 "y.tab.c"
+ break;
+
+ case 9: /* call: call '.' name */
+#line 99 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+ {
+ size_t len = strlen((yyvsp[-2].str)) + strlen((yyvsp[0].str)) + 4; // "[name call]"
+ (yyval.str) = malloc(len);
+ snprintf((yyval.str), len, "[%s %s]", (yyvsp[0].str), (yyvsp[-2].str));
+ free((yyvsp[0].str));
+ free((yyvsp[-2].str));
+ }
+#line 1242 "y.tab.c"
+ break;
+
+ case 10: /* content: name content */
+#line 108 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+ {
+ size_t len = strlen((yyvsp[-1].str)) + strlen((yyvsp[0].str)) + 1;
+ (yyval.str) = malloc(len);
+ snprintf((yyval.str), len, "%s%s", (yyvsp[-1].str), (yyvsp[0].str));
+ free((yyvsp[-1].str));
+ free((yyvsp[0].str));
+ }
+#line 1254 "y.tab.c"
+ break;
+
+ case 11: /* content: CONTENT */
+#line 115 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+ {
+ (yyval.str) = strdup((yyvsp[0].str));
+ }
+#line 1262 "y.tab.c"
+ break;
+
+ case 12: /* content: %empty */
+#line 118 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+ {
+ (yyval.str) = strdup("");
+ }
+#line 1270 "y.tab.c"
+ break;
+
+ case 13: /* name: NAME */
+#line 124 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+ { (yyval.str) = strdup((yyvsp[0].str)); }
+#line 1276 "y.tab.c"
+ break;
+
+
+#line 1280 "y.tab.c"
+
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+
+ *++yyvsp = yyval;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+ ? yytable[yyi]
+ : yydefgoto[yylhs]);
+ }
+
+ goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar);
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+ yyerror (YY_("syntax error"));
+ }
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+ /* Pacify compilers when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
+ ++yynerrs;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ /* Pop stack until we find a state that shifts the error token. */
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYSYMBOL_YYerror;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ YY_ACCESSING_SYMBOL (yystate), yyvsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturnlab;
+
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturnlab;
+
+
+/*-----------------------------------------------------------.
+| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
+`-----------------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ goto yyreturnlab;
+
+
+/*----------------------------------------------------------.
+| yyreturnlab -- parsing is finished, clean up and return. |
+`----------------------------------------------------------*/
+yyreturnlab:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ }
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ YY_ACCESSING_SYMBOL (+*yyssp), yyvsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+
+ return yyresult;
+}
+
+#line 126 "/mnt/c/Users/julic/OneDrive/Documentos/Projetos/vinum/vinum/src/sweet_bison.y"
+
+
+
diff --git a/subprojects/vinumc/config.log b/subprojects/vinumc/config.log
new file mode 100644
index 0000000..94db48a
--- /dev/null
+++ b/subprojects/vinumc/config.log
@@ -0,0 +1,236 @@
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by vinum configure 1.0, which was
+generated by GNU Autoconf 2.71. Invocation command line was
+
+ $ ../configure
+
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = compiuter
+uname -m = x86_64
+uname -r = 5.15.167.4-microsoft-standard-WSL2
+uname -s = Linux
+uname -v = #1 SMP Tue Nov 5 00:21:55 UTC 2024
+
+/usr/bin/uname -p = x86_64
+/bin/uname -X = unknown
+
+/bin/arch = x86_64
+/usr/bin/arch -k = unknown
+/usr/convex/getsysinfo = unknown
+/usr/bin/hostinfo = unknown
+/bin/machine = unknown
+/usr/bin/oslevel = unknown
+/bin/universe = unknown
+
+PATH: /usr/local/sbin/
+PATH: /usr/local/bin/
+PATH: /usr/sbin/
+PATH: /usr/bin/
+PATH: /sbin/
+PATH: /bin/
+PATH: /usr/games/
+PATH: /usr/local/games/
+PATH: /usr/lib/wsl/lib/
+PATH: /mnt/c/Windows/system32/
+PATH: /mnt/c/Windows/
+PATH: /mnt/c/Windows/System32/Wbem/
+PATH: /mnt/c/Windows/System32/WindowsPowerShell/v1.0/
+PATH: /mnt/c/Windows/System32/OpenSSH/
+PATH: /mnt/c/Program Files/dotnet/
+PATH: /mnt/c/Program Files/NVIDIA Corporation/NVIDIA NvDLISR/
+PATH: /mnt/c/WINDOWS/system32/
+PATH: /mnt/c/WINDOWS/
+PATH: /mnt/c/WINDOWS/System32/Wbem/
+PATH: /mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/
+PATH: /mnt/c/WINDOWS/System32/OpenSSH/
+PATH: /mnt/c/Program Files/Git/cmd/
+PATH: /mnt/c/ProgramData/chocolatey/bin/
+PATH: /mnt/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common/
+PATH: /Docker/host/bin/
+PATH: /mnt/c/Program Files/Go/bin/
+PATH: /mnt/c/Users/arthu/.cargo/bin/
+PATH: /mnt/c/Users/arthu/AppData/Local/Microsoft/WindowsApps/
+PATH: /mnt/c/Users/arthu/AppData/Local/Programs/Microsoft VS Code/bin/
+PATH: /mnt/c/Program Files/zstd-v1.5.6-win64/
+PATH: /mnt/c/Users/arthu/go/bin/
+PATH: /mnt/c/users/arthu/appdata/local/packages/pythonsoftwarefoundation.python.3.12_qbz5n2kfra8p0/localcache/local-packages/python312/scripts/
+PATH: /mnt/c/users/arthu/.local/bin/
+PATH: /mnt/c/Users/arthu/AppData/Roaming/nvm/
+PATH: /mnt/c/Program Files/nodejs/
+PATH: /home/vergacas/.local/bin/
+PATH: /usr/local/go/bin/
+PATH: /home/vergacas/.local/bin/
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+configure:2154: looking for aux files: compile missing install-sh
+configure:2167: trying ../
+configure:2196: ../compile found
+configure:2196: ../missing found
+configure:2178: ../install-sh found
+configure:2325: checking for a BSD-compatible install
+configure:2398: result: /usr/bin/install -c
+configure:2409: checking whether build environment is sane
+configure:2464: result: yes
+configure:2623: checking for a race-free mkdir -p
+configure:2667: result: /usr/bin/mkdir -p
+configure:2674: checking for gawk
+configure:2695: found /usr/bin/gawk
+configure:2706: result: gawk
+configure:2717: checking whether make sets $(MAKE)
+configure:2740: result: yes
+configure:2770: checking whether make supports nested variables
+configure:2788: result: yes
+configure:2805: error: source directory already configured; run "make distclean" there first
+
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+
+ac_cv_env_CC_set=
+ac_cv_env_CC_value=
+ac_cv_env_CFLAGS_set=
+ac_cv_env_CFLAGS_value=
+ac_cv_env_CPPFLAGS_set=
+ac_cv_env_CPPFLAGS_value=
+ac_cv_env_LDFLAGS_set=
+ac_cv_env_LDFLAGS_value=
+ac_cv_env_LIBS_set=
+ac_cv_env_LIBS_value=
+ac_cv_env_YACC_set=
+ac_cv_env_YACC_value=
+ac_cv_env_YFLAGS_set=
+ac_cv_env_YFLAGS_value=
+ac_cv_env_build_alias_set=
+ac_cv_env_build_alias_value=
+ac_cv_env_host_alias_set=
+ac_cv_env_host_alias_value=
+ac_cv_env_target_alias_set=
+ac_cv_env_target_alias_value=
+ac_cv_path_install='/usr/bin/install -c'
+ac_cv_path_mkdir=/usr/bin/mkdir
+ac_cv_prog_AWK=gawk
+ac_cv_prog_make_make_set=yes
+am_cv_make_support_nested_variables=yes
+
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+
+ACLOCAL=''
+AMDEPBACKSLASH=''
+AMDEP_FALSE=''
+AMDEP_TRUE=''
+AMTAR=''
+AM_BACKSLASH='\'
+AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+AM_DEFAULT_VERBOSITY='1'
+AM_V='$(V)'
+AUTOCONF=''
+AUTOHEADER=''
+AUTOMAKE=''
+AWK='gawk'
+CC=''
+CCDEPMODE=''
+CFLAGS=''
+CPPFLAGS=''
+CSCOPE=''
+CTAGS=''
+CYGPATH_W=''
+DEFS=''
+DEPDIR=''
+ECHO_C=''
+ECHO_N='-n'
+ECHO_T=''
+ETAGS=''
+EXEEXT=''
+INSTALL_DATA='${INSTALL} -m 644'
+INSTALL_PROGRAM='${INSTALL}'
+INSTALL_SCRIPT='${INSTALL}'
+INSTALL_STRIP_PROGRAM='$(install_sh) -c -s'
+LDFLAGS=''
+LEX=''
+LEXLIB=''
+LEX_OUTPUT_ROOT=''
+LIBOBJS=''
+LIBS=''
+LTLIBOBJS=''
+MAKEINFO=''
+MKDIR_P='/usr/bin/mkdir -p'
+OBJEXT=''
+PACKAGE=''
+PACKAGE_BUGREPORT=''
+PACKAGE_NAME='vinum'
+PACKAGE_STRING='vinum 1.0'
+PACKAGE_TARNAME='vinum'
+PACKAGE_URL=''
+PACKAGE_VERSION='1.0'
+PATH_SEPARATOR=':'
+SET_MAKE=''
+SHELL='/bin/bash'
+STRIP=''
+VERSION=''
+YACC=''
+YFLAGS=''
+ac_ct_CC=''
+am__EXEEXT_FALSE=''
+am__EXEEXT_TRUE=''
+am__fastdepCC_FALSE=''
+am__fastdepCC_TRUE=''
+am__include=''
+am__isrc=' -I$(srcdir)'
+am__leading_dot='.'
+am__nodep=''
+am__quote=''
+am__tar=''
+am__untar=''
+bindir='${exec_prefix}/bin'
+build_alias=''
+datadir='${datarootdir}'
+datarootdir='${prefix}/share'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+dvidir='${docdir}'
+exec_prefix='NONE'
+host_alias=''
+htmldir='${docdir}'
+includedir='${prefix}/include'
+infodir='${datarootdir}/info'
+install_sh='${SHELL} /home/vergacas/ic/vinum/install-sh'
+libdir='${exec_prefix}/lib'
+libexecdir='${exec_prefix}/libexec'
+localedir='${datarootdir}/locale'
+localstatedir='${prefix}/var'
+mandir='${datarootdir}/man'
+mkdir_p=''
+oldincludedir='/usr/include'
+pdfdir='${docdir}'
+prefix='NONE'
+program_transform_name='s,x,x,'
+psdir='${docdir}'
+runstatedir='${localstatedir}/run'
+sbindir='${exec_prefix}/sbin'
+sharedstatedir='${prefix}/com'
+sysconfdir='${prefix}/etc'
+target_alias=''
+
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+
+/* confdefs.h */
+#define PACKAGE_NAME "vinum"
+#define PACKAGE_TARNAME "vinum"
+#define PACKAGE_VERSION "1.0"
+#define PACKAGE_STRING "vinum 1.0"
+#define PACKAGE_BUGREPORT ""
+#define PACKAGE_URL ""
+
+configure: exit 1
diff --git a/subprojects/vinumc/dry_bison.y b/subprojects/vinumc/dry_bison.y
index 6ecf95b..1214411 100644
--- a/subprojects/vinumc/dry_bison.y
+++ b/subprojects/vinumc/dry_bison.y
@@ -28,7 +28,7 @@ program:
struct ast_node node = ast_node_new_nvl(PROGRAM);
$$ = ast_add_node(&ctx.ast, node);
}
- | program args {
+ | program block {
struct ast_node *node = &VEC_AT(&ctx.ast.nodes, $1);
ast_node_add_child(node, $2);
@@ -120,7 +120,7 @@ symbol: WORD {
wchar_t *wtext = (wchar_t*)malloc(len * sizeof(wchar_t));
// TODO: handle the function return value
mbstowcs(wtext, text, len);
-
+
for(size_t i = 0; i < len; i++) {
wtext[i] = towlower(wtext[i]);
}
diff --git a/subprojects/vinumc/eval.c b/subprojects/vinumc/eval.c
index 08d6868..dacb318 100644
--- a/subprojects/vinumc/eval.c
+++ b/subprojects/vinumc/eval.c
@@ -117,9 +117,9 @@ RESOLVE_FUNC_SIGNATURE(resolve_calls_descent) {
RESOLVE_FUNC_SIGNATURE(resolve_calls_call) {
struct scope *curr_scope = &VEC_AT(&ctx->scopes, curr_scope_id);
- struct ast_node ast_node = VEC_AT(&ast->nodes, ast_node_id);
+ struct ast_node *ast_node = &VEC_AT(&ast->nodes, ast_node_id);
- char *call_name = VEC_AT(&ast->nodes, VEC_AT(&ast_node.childs, 0)).text;
+ char *call_name = VEC_AT(&ast->nodes, VEC_AT(&ast_node->childs, 0)).text;
if (call_name == NULL) {
fprintf(stderr, "ERROR: Symbol with no name\n");
return;
@@ -130,9 +130,9 @@ RESOLVE_FUNC_SIGNATURE(resolve_calls_call) {
if (symbol_info != NULL) {
if (symbol_info->type == ENTRY_INTERNAL) {
- if (ast_node.childs.len > 1) {
+ if (ast_node->childs.len > 1) {
if (symbol_info->as.ast_node_id < 0) {
- ast_node.childs.len--;
+ ast_node->childs.len--;
return;
}
@@ -147,26 +147,31 @@ RESOLVE_FUNC_SIGNATURE(resolve_calls_call) {
if (child->type == ARG_REF_ALL_ARGS) {
VEC_AT(&symbol_args_node->childs, i) =
- VEC_AT(&ast_node.childs, 1);
+ VEC_AT(&ast_node->childs, 1);
}
}
- VEC_AT(&VEC_AT(&ast->nodes, ast_node_id).childs, 1) =
- symbol_args_node_id;
+ VEC_AT(&ast_node->childs, 1) = symbol_args_node_id;
} else {
if (symbol_info->as.ast_node_id >= 0) {
- ast_node_add_child(&VEC_AT(&ast->nodes, ast_node_id),
- symbol_info->as.ast_node_id);
+ ast_node_add_child(ast_node, symbol_info->as.ast_node_id);
}
}
- size_t new_node = VEC_AT(&VEC_AT(&ast->nodes, ast_node_id).childs, 1);
+ size_t new_node = VEC_AT(&ast_node->childs, 1);
resolve_symbols(ctx, ast, curr_scope_id, new_node);
} else if (symbol_info->type == ENTRY_EXTERNAL) {
struct ast_node *symbol_node =
- &VEC_AT(&ast->nodes, VEC_AT(&ast_node.childs, 0));
+ &VEC_AT(&ast->nodes, VEC_AT(&ast_node->childs, 0));
symbol_node->type = FUNCTION;
+
+ if (ast_node->childs.len <= 1) {
+ // ensure that the call node has an ARGS node
+ // to prevent it from being skipped during evaluation
+ size_t args_node_id = ast_add_node(ast, ast_node_new_nvl(ARGS));
+ ast_node_add_child(ast_node, args_node_id);
+ }
}
} else {
fprintf(stderr, "ERROR: No symbol with name \"%s\" exist\n", call_name);
diff --git a/subprojects/vinumc/meson.build b/subprojects/vinumc/meson.build
index 937ec09..c935627 100644
--- a/subprojects/vinumc/meson.build
+++ b/subprojects/vinumc/meson.build
@@ -40,7 +40,11 @@ vinumc_dep = declare_dependency(
include_directories : inc,
)
-dl_dep = dependency('dl')
+if meson.version().version_compare('>=0.62.0')
+ dl_dep = dependency('dl')
+else
+ dl_dep = meson.get_compiler('c').find_library('dl', required: true)
+endif
headers = [
'include/extern_library.h',
diff --git a/subprojects/vinumc/meson.options b/subprojects/vinumc/meson_options.txt
similarity index 100%
rename from subprojects/vinumc/meson.options
rename to subprojects/vinumc/meson_options.txt
diff --git a/subprojects/vinumc/sweet_bison.h b/subprojects/vinumc/sweet_bison.h
new file mode 100644
index 0000000..8eb1c78
--- /dev/null
+++ b/subprojects/vinumc/sweet_bison.h
@@ -0,0 +1,93 @@
+/* A Bison parser, made by GNU Bison 3.8.2. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+ especially those whose name start with YY_ or yy_. They are
+ private implementation details that can be changed or removed. */
+
+#ifndef YY_YY_SWEET_BISON_H_INCLUDED
+# define YY_YY_SWEET_BISON_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token kinds. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ YYEMPTY = -2,
+ YYEOF = 0, /* "end of file" */
+ YYerror = 256, /* error */
+ YYUNDEF = 257, /* "invalid token" */
+ NAME = 258, /* NAME */
+ CONTENT = 259 /* CONTENT */
+ };
+ typedef enum yytokentype yytoken_kind_t;
+#endif
+/* Token kinds. */
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYerror 256
+#define YYUNDEF 257
+#define NAME 258
+#define CONTENT 259
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+union YYSTYPE
+{
+#line 21 "sweet_bison.y"
+
+ char* str;
+
+#line 79 "sweet_bison.h"
+
+};
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE yylval;
+
+
+int yyparse (void);
+
+
+#endif /* !YY_YY_SWEET_BISON_H_INCLUDED */
diff --git a/subprojects/vinumc/sweet_bison.y b/subprojects/vinumc/sweet_bison.y
new file mode 100644
index 0000000..0cb93a1
--- /dev/null
+++ b/subprojects/vinumc/sweet_bison.y
@@ -0,0 +1,194 @@
+%{
+#include
+#include
+#include
+
+#include "sweet_vinumc.h"
+
+// Forward declaration
+int yylex();
+
+// Utility function declarations
+char* concat(const char* a, const char* b);
+char* format_block(const char* name, const char* content);
+char* format_call(const char* outer, const char* inner);
+char* put_in_chain(const char* inner_block, const char* call_chain);
+
+// Output file pointer
+extern FILE* output_file;
+%}
+
+%union {
+ char* str;
+}
+
+%token NAME CONTENT
+%type program block call final_
+
+%%
+
+// Entry point of the parser; prints the fully transpiled result
+final_:
+ program {
+ $$ = strdup($1);
+ free($1);
+ if (output_file) {
+ fprintf(output_file, "%s", $$);
+ }
+ }
+;
+
+// Program: sequence of blocks or empty
+program:
+ /* empty */ { $$ = strdup(""); }
+ | program block {
+ $$ = concat($1, $2);
+ free($1);
+ free($2);
+ }
+;
+
+// Block constructs
+block:
+ // Parenthesized block
+ '(' program ')' {
+ size_t len = strlen($2) + 3;
+ $$ = malloc(len);
+ snprintf($$, len, "(%s)", $2);
+ free($2);
+ }
+ // Parenthesized block with call chain
+ | '(' program ')' '.' NAME call {
+ char* first_block = format_block($5, $2);
+ char* chained_block = put_in_chain(first_block, $6);
+ $$ = format_block(chained_block, "");
+ free($5);
+ free($2);
+ free($6);
+ }
+ // Parenthesized block with single call
+ | '(' program ')' call {
+ $$ = format_block($4, $2);
+ free($4);
+ free($2);
+ }
+ // Call without arguments block
+ | call {
+ $$ = format_block($1, "");
+ free($1);
+ }
+ // Raw content
+ | CONTENT {
+ $$ = strdup($1);
+ free($1);
+ }
+;
+
+// Chained function calls
+call:
+ '.' NAME {
+ $$ = strdup($2);
+ free($2);
+ }
+ | call '.' NAME {
+ $$ = format_call($3, $1);
+ free($1);
+ free($3);
+ }
+;
+
+%%
+
+/**
+ * Concatenates two strings. If either string is empty, returns a copy of the other.
+ *
+ * @param a First string
+ * @param b Second string
+ * @return Concatenated result
+ */
+char* concat(const char* a, const char* b) {
+ if (strlen(a) == 0) return strdup(b);
+ if (strlen(b) == 0) return strdup(a);
+
+ size_t len = strlen(a) + strlen(b) + 2; // +1 for NULL and extra safety
+ char* result = malloc(len);
+ snprintf(result, len, "%s%s", a, b);
+ return result;
+}
+
+/**
+ * Formats a function block in the dry flavor: [name content] or [name] if content is empty.
+ *
+ * @param name Function name
+ * @param content Block content
+ * @return Formatted dry-style block
+ */
+char* format_block(const char* name, const char* content) {
+ size_t len = strlen(name) + strlen(content) + 4; // [], space and NULL
+ char* result = malloc(len);
+
+ if (strlen(content) > 0)
+ snprintf(result, len, "[%s %s]", name, content);
+ else
+ snprintf(result, len, "[%s]", name);
+
+ return result;
+}
+
+/**
+ * Formats a function call inside another: returns a string like `outer [inner]`.
+ *
+ * @param outer Outer function name
+ * @param inner Inner block
+ * @return Nested block string
+ */
+char* format_call(const char* outer, const char* inner) {
+ size_t len = strlen(outer) + strlen(inner) + 5; // '[', ' ', ']', NULL
+ char* result = malloc(len);
+ snprintf(result, len, "%s [%s]", outer, inner);
+ return result;
+}
+
+/**
+ * Inserts an inner block into the last nested position of a call chain.
+ *
+ * For example:
+ * call_chain = "bar [baz [qux]]"
+ * inner_block = "[foo content]"
+ * result = "bar [baz [qux [foo content]]]"
+ *
+ * @param inner_block The block to be inserted (e.g., "[foo content]")
+ * @param call_chain The chain of nested calls (e.g., "bar [baz [qux]]")
+ * @return A newly allocated string with inner_block inserted at the correct position.
+ */
+char* put_in_chain(const char* inner_block, const char* call_chain) {
+ if (!call_chain || strlen(call_chain) == 0) {
+ return strdup(inner_block);
+ }
+
+ size_t call_len = strlen(call_chain);
+ size_t inner_len = strlen(inner_block);
+
+ // Find the position where the final ']' sequence starts
+ ssize_t i = call_len - 1;
+ while (i >= 0 && call_chain[i] == ']') {
+ i--;
+ }
+ i++;
+
+ // Split the call_chain into prefix and suffix
+ char* prefix = strndup(call_chain, i);
+ char* suffix = strdup(&call_chain[i]);
+
+ size_t result_len = strlen(prefix) + inner_len + strlen(suffix) + 2; // +1 for space +1 for '\0'
+ char* result = malloc(result_len);
+
+ // Format the final string
+ snprintf(result, result_len, "%s %s%s", prefix, inner_block, suffix);
+
+ // Clean up temporary strings
+ free(prefix);
+ free(suffix);
+
+ return result;
+}
diff --git a/subprojects/vinumc/sweet_flex.l b/subprojects/vinumc/sweet_flex.l
new file mode 100644
index 0000000..370f32c
--- /dev/null
+++ b/subprojects/vinumc/sweet_flex.l
@@ -0,0 +1,57 @@
+%option noyywrap nodefault yylineno
+
+%{
+#include
+#include
+#include
+#include "sweet_bison.h"
+#include "sweet_vinumc.h"
+
+#define YY_NO_INPUT
+%}
+
+/* Define custom lexer state */
+%s AFTER_DOT
+
+%%
+
+"(" { return '('; }
+")" { return ')'; }
+
+"."[a-zA-Z_] {
+/* Dot followed by identifier: return dot and leave identifier for next token */
+ unput(yytext[1]);
+/* Switch to AFTER_DOT mode */
+ BEGIN(AFTER_DOT);
+ return '.';
+}
+
+[a-zA-Z_][a-zA-Z0-9_]* {
+/* In AFTER_DOT state: match NAME */
+ yylval.str = strdup(yytext);
+ BEGIN(INITIAL); // back to default state
+ return NAME;
+}
+
+. {
+/* In AFTER_DOT state: fallback to CONTENT and revert state */
+ // Not a valid NAME after dot, treat it as content
+ char* s = malloc(strlen(yytext) + 2);
+ snprintf(s, strlen(yytext) + 2, "%s", yytext);
+ yylval.str = s;
+ BEGIN(INITIAL);
+ return CONTENT;
+}
+
+[ \t\n]+ {
+/* Whitespace or newline: CONTENT */
+ yylval.str = strdup(yytext);
+ return CONTENT;
+}
+
+. {
+/* Any other character: also CONTENT */
+ yylval.str = strdup(yytext);
+ return CONTENT;
+}
+%%
diff --git a/subprojects/vinumc/sweet_vinumc.c b/subprojects/vinumc/sweet_vinumc.c
new file mode 100644
index 0000000..c906126
--- /dev/null
+++ b/subprojects/vinumc/sweet_vinumc.c
@@ -0,0 +1,105 @@
+#include
+#include
+#include
+#include
+
+#include "sweet_vinumc.h"
+
+// External lexer input file pointer
+extern FILE *yyin;
+
+// Output file to write the dry result
+FILE *output_file = NULL;
+
+/**
+ * Error reporting function for the Bison parser.
+ *
+ * Accepts a printf-style format and optional arguments.
+ *
+ * @param s Format string
+ */
+void yyerror(char *s, ...) {
+ va_list ap;
+ va_start(ap, s);
+
+ fprintf(stderr, "[ERROR]: ");
+ vfprintf(stderr, s, ap);
+ fprintf(stderr, "\n");
+
+ va_end(ap);
+}
+
+/**
+ * Creates a new string with the same base as the input filename,
+ * but with the suffix "_dry.vin".
+ *
+ * For example: input "foo.vin" → output "foo_dry.vin"
+ *
+ * @param filename Original input filename
+ * @return Newly allocated output filename with "_dry.vin" suffix
+ */
+char* append_dry_suffix(const char* filename) {
+ const char* dot = strrchr(filename, '.');
+ size_t base_len = dot ? (size_t)(dot - filename) : strlen(filename);
+ const char* suffix = "_dry.vin";
+ size_t result_len = base_len + strlen(suffix) + 1;
+
+ char* result = malloc(result_len);
+ if (!result) {
+ fprintf(stderr, "Memory allocation error.\n");
+ exit(1);
+ }
+
+ strncpy(result, filename, base_len);
+ result[base_len] = '\0';
+ strcat(result, suffix);
+ return result;
+}
+
+/**
+ * Entry point of the transpiler.
+ *
+ * Opens the sweet-style source file, parses it using Flex/Bison,
+ * and writes the dry-style output to a new file.
+ *
+ * @param argc Number of command-line arguments
+ * @param argv Array of command-line arguments
+ * @return Exit code (0 on success, 1 on error)
+ */
+int main(int argc, char *argv[]) {
+ // Require input file argument
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s \n", argv[0]);
+ return 1;
+ }
+
+ const char* input_filename = argv[1];
+ FILE* input = fopen(input_filename, "r");
+ if (!input) {
+ perror("Error opening input file");
+ return 1;
+ }
+
+ // Set Flex to read from input file
+ yyin = input;
+
+ // Generate output filename
+ char* output_filename = append_dry_suffix(input_filename);
+ output_file = fopen(output_filename, "w");
+ if (!output_file) {
+ perror("Error creating output file");
+ fclose(input);
+ free(output_filename);
+ return 1;
+ }
+
+ // Parse input file
+ int status = yyparse();
+
+ // Cleanup
+ fclose(input);
+ fclose(output_file);
+ free(output_filename);
+
+ return status;
+}
diff --git a/subprojects/vinumc/sweet_vinumc.h b/subprojects/vinumc/sweet_vinumc.h
new file mode 100644
index 0000000..1e7648b
--- /dev/null
+++ b/subprojects/vinumc/sweet_vinumc.h
@@ -0,0 +1,7 @@
+#ifndef __SWEET_VINUMC_H__
+#define __SWEET_VINUMC_H__
+
+void yyerror(char *s, ...);
+int yyparse();
+
+#endif // __SWEET_VINUMC_H__
diff --git a/subprojects/vinumc/tests/library_test.c b/subprojects/vinumc/tests/library_test.c
index d2ff3ec..63d4e55 100644
--- a/subprojects/vinumc/tests/library_test.c
+++ b/subprojects/vinumc/tests/library_test.c
@@ -29,6 +29,16 @@ void test_empty_nested_call(struct vunit_test_ctx *ctx) {
VUNIT_ASSERT_STREQ(ctx, out, "");
}
+void test_call_no_args(struct vunit_test_ctx *ctx) {
+ char *out = NULL;
+
+ vunit_run_vinumc_ok(ctx, "[parenthesize]", &out, "--with",
+ "subprojects/vinumc/tests/libtestlib.so", NULL);
+
+ VUNIT_ASSERT_STREQ(ctx, out, "()");
+}
+
VUNIT_TEST_SUITE("suite", { "Test extern library call", test_call },
{ "Test extern library call inside call", test_nested_call },
- { "Test nested empty library calls", test_empty_nested_call }, {}, )
+ { "Test nested empty library calls", test_empty_nested_call },
+ { "Test extern library call with no arguments", test_call_no_args }, {}, )
diff --git a/subprojects/vinumc/tests/meson.build b/subprojects/vinumc/tests/meson.build
index 1d97a27..49aaeda 100644
--- a/subprojects/vinumc/tests/meson.build
+++ b/subprojects/vinumc/tests/meson.build
@@ -5,13 +5,12 @@ tests = [
'library_test.c',
'output_flag_test.c',
'simple_test.c',
- 'text_as_program_child_test.c',
]
vunit_dep = dependency('vunit', fallback : ['vunit', 'vunit_dep'])
foreach t : tests
- basename = fs.stem(t)
+ basename = fs.stem(t)
test_exe = executable(
basename,
@@ -22,13 +21,18 @@ foreach t : tests
test_env = environment()
test_env.prepend('PATH', fs.parent(vinumc.full_path()))
+ test_kwargs = {}
+ if meson.version().version_compare('>=0.62.0')
+ test_kwargs += {'verbose': true}
+ endif
+
test(
basename,
test_exe,
env : test_env,
protocol : 'tap',
- verbose : true,
depends: vinumc,
+ kwargs: test_kwargs,
)
endforeach
diff --git a/subprojects/vinumc/tests/testlib.c b/subprojects/vinumc/tests/testlib.c
index 322d03d..d4c14d0 100644
--- a/subprojects/vinumc/tests/testlib.c
+++ b/subprojects/vinumc/tests/testlib.c
@@ -1,10 +1,26 @@
#include "extern_library.h"
+#include
+#include
struct return_value return_arg(char *arg) {
return (struct return_value){ .ptr = arg };
}
+struct return_value parenthesize(char *arg) {
+ size_t len = strlen(arg);
+ char *result = malloc(len + 3);
+
+ result[0] = '(';
+ memcpy(result + 1, arg, len);
+ result[len + 1] = ')';
+ result[len + 2] = '\0';
+
+ return (struct return_value){ .ptr = result, .free = true };
+}
+
struct extern_function *expose_library() {
- static struct extern_function lib[] = { { "return_arg", return_arg }, {} };
+ static struct extern_function lib[] = { { "return_arg", return_arg },
+ { "parenthesize", parenthesize },
+ {} };
return lib;
}
diff --git a/subprojects/vinumc/tests/text_as_program_child_test.c b/subprojects/vinumc/tests/text_as_program_child_test.c
deleted file mode 100644
index 58d5b7a..0000000
--- a/subprojects/vinumc/tests/text_as_program_child_test.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include
-
-void test_simple_text(struct vunit_test_ctx *ctx) {
- char *out = NULL;
-
- vunit_run_vinumc_ok(ctx, "Hello World!", &out, NULL);
-
- VUNIT_ASSERT_STREQ(ctx, out, "Hello World!\n");
-}
-
-void test_mixed_text_and_blocks(struct vunit_test_ctx *ctx) {
- char *out = NULL;
-
- vunit_run_vinumc_ok(ctx,
- "Hello [a]\n"
- "[a: World!]\n",
- &out, NULL);
-
- VUNIT_ASSERT_STREQ(ctx, out, "Hello\nWorld!\n");
-}
-
-void test_ref_all_args_is_empty(struct vunit_test_ctx *ctx) {
- char *out = NULL;
-
- vunit_run_vinumc_ok(ctx, "$*", &out, NULL);
-
- VUNIT_ASSERT_STREQ(ctx, out, "");
-}
-
-VUNIT_TEST_SUITE("suite", { "Simple text", test_simple_text },
- { "Mixed text and blocks", test_mixed_text_and_blocks },
- { "Ref all args is empty", test_ref_all_args_is_empty }, {}, )