reorganize main source and examples, flesh out build.sh, fill in basics of symbol_set.starter.h

main
Allen Webster 2026-02-23 14:46:01 -08:00
parent e1fc795db4
commit 18c97e6804
21 changed files with 205 additions and 250 deletions

View File

@ -1,15 +1,32 @@
#!/bin/bash
###############
# SETUP PATHS #
###############
root_path="$PWD"
build_path="$root_path/build"
src_path="$root_path/src"
src_path="$root_path"
examples_path="$root_path/examples"
###############
# SETUP BUILD #
###############
mkdir -p $build_path
cd $build_path
rm *
######################
# BUILD META PROGRAM #
######################
clang -o sy.ld_meta $src_path/symbol_set.ld_meta.c -I$src_path/mr4th
clang -c -o example1.o $src_path/example1.c
./sy.ld_meta --out:example1_sy.ld example1.o
clang -o example1 example1.o -T example1_sy.ld
#######################
# BUILD hello_world.c #
#######################
clang -c -o hello_world.o $examples_path/hello_world.c -I$src_path
./sy.ld_meta --out:hello_world_sy.ld hello_world.o
clang -o hello_world hello_world.o -T hello_world_sy.ld

69
examples/hello_world.c Normal file
View File

@ -0,0 +1,69 @@
/***********************************************************
** symbol_set - A public domain C modifier library
** by Allen Webster, "Mr. 4th", allenw@mr4th.com
**
** No warranty implied; use at your own risk
**
** Read README to get started.
*/
#include "symbol_set.h"
#include "hello_world.h"
#include <stdio.h>
#include "symbol_set.c"
COMMAND_DEF(Punctuate, "Prints a punctuation", 0){
printf("!");
}
COMMAND_DEF(Address, "Prints an address to the audience", 1){
printf("World");
}
COMMAND_DEF(Greet, "Prints a greeting", 1){
printf("Hello");
}
int main(void){
// display the legend of rules
printf("RULES:\n");
for (SyEach(COMMAND, command)){
printf("%s -> %s\n", command->name, command->description);
}
printf("\n");
// init the sequence
Sy_U32 sequence[] = {
SyID(COMMAND, Greet), SyID(COMMAND, Address), SyID(COMMAND, Punctuate),
};
// display the sequence
printf("SEQUENCE:\n");
for (Sy_U32 i = 0; i < sizeof(sequence)/sizeof(sequence[0]); i += 1){
Sy_U32 id = sequence[i];
Command *command = SyAddressFromID(COMMAND, id);
printf("%s, ", command->name);
}
printf("\n\n");
// run the sequence
printf("OUTPUT:\n");
{
int prev_was_word = 0;
for (Sy_U32 i = 0; i < sizeof(sequence)/sizeof(sequence[0]); i += 1){
Sy_U32 id = sequence[i];
Command *command = SyAddressFromID(COMMAND, id);
if (command->is_word && prev_was_word){
printf(" ");
}
command->hook();
prev_was_word = command->is_word;
}
}
printf("\n");
return(0);
}

24
examples/hello_world.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef HELLO_WORLD_H
#define HELLO_WORLD_H
typedef void Hook(void);
typedef struct Command{
char *name;
char *description;
Hook *hook;
int is_word;
} Command;
#define SYMBOL_SET_DEFINE COMMAND
#define COMMAND_Type Command
#define COMMAND_section ".sy.cmd"
#define COMMAND_marker cmd
#include "symbol_set.define.h"
#define COMMAND_DEF(N,desc,is_word) \
void cmd_##N(void); \
SyDefine(COMMAND, N) = { #N, desc, cmd_##N, (is_word) };\
void cmd_##N(void)
#endif /* HELLO_WORLD_H */

View File

@ -1,38 +0,0 @@
version(2);
project_name = "example1";
patterns = {
"*.c",
"*.cpp",
"*.h",
"*.m",
"*.bat",
"*.sh",
"*.4coder",
"*.txt",
};
blacklist_patterns = {
".*",
};
load_paths_base = {
{ ".", .relative = true, .recursive = true, },
};
load_paths = {
.win = load_paths_base,
.linux = load_paths_base,
.mac = load_paths_base,
};
commands = {
.build = { .out = "*compilation*", .footer_panel = true, .save_dirty_files = true,
.win = "build.bat",
.linux = "./build.sh",
.mac = "./build.sh", },
.run = { .out = "*run*", .footer_panel = false, .save_dirty_files = false,
.win = "build\\example1",
.linux = "build/example1",
.mac = "build/example1", },
};
fkey_command = {
.F1 = "build",
.F2 = "run",
};

View File

@ -1,68 +0,0 @@
/*
** C Scripting Example #1
*/
#include "symbol_set.h"
#include "example1.h"
#include <stdio.h>
#include "symbol_set.c"
EX1_COMMAND_DEF(Hello, "Increments and prints the counter"){
ctx->counter += 1;
printf("Hello World! (%d)\n", ctx->counter);
}
EX1_COMMAND_DEF(Goodbye, "Prints and decrements the counter"){
printf("Goodbye! (%d)\n", ctx->counter);
ctx->counter -= 1;
}
EX1_COMMAND_DEF(UntilNextTime, "Resets the counter and prints"){
ctx->counter = 0;
printf("Until next time...\n");
}
int main(void){
// display the legend of rules
printf("RULES:\n");
for (SyEach(EX1_COMMAND, command)){
printf("%s -> %s\n", command->name, command->description);
}
printf("\n");
// init the sequence
Sy_U32 sequence[] = {
SyID(EX1_COMMAND, Hello), SyID(EX1_COMMAND, Hello),
SyID(EX1_COMMAND, UntilNextTime),
SyID(EX1_COMMAND, Hello), SyID(EX1_COMMAND, Goodbye),
SyID(EX1_COMMAND, Hello), SyID(EX1_COMMAND, Goodbye),
SyID(EX1_COMMAND, UntilNextTime),
SyID(EX1_COMMAND, Goodbye), SyID(EX1_COMMAND, Goodbye),
SyID(EX1_COMMAND, Goodbye), SyID(EX1_COMMAND, Hello),
SyID(EX1_COMMAND, Hello), SyID(EX1_COMMAND, Hello),
};
// display the sequence
printf("SEQUENCE:\n");
for (Sy_U32 i = 0; i < sizeof(sequence)/sizeof(sequence[0]); i += 1){
Sy_U32 id = sequence[i];
EX1_Command *command = SyAddressFromID(EX1_COMMAND, id);
printf("%s, ", command->name);
}
printf("\n\n");
// run the sequence
printf("OUTPUT:\n");
{
EX1_Ctx ctx = {0};
for (Sy_U32 i = 0; i < sizeof(sequence)/sizeof(sequence[0]); i += 1){
Sy_U32 id = sequence[i];
EX1_Command *command = SyAddressFromID(EX1_COMMAND, id);
command->hook(&ctx);
}
}
return(0);
}

View File

@ -1,30 +0,0 @@
#ifndef EXAMPLE1_H
#define EXAMPLE1_H
////////////////////////////////
// Setup a Symbol Set
typedef struct EX1_Ctx{
int counter;
} EX1_Ctx;
typedef void EX1_Hook(EX1_Ctx *ctx);
typedef struct EX1_Command{
char *name;
char *description;
EX1_Hook *hook;
} EX1_Command;
#define SYMBOL_SET_DEFINE EX1_COMMAND
#define EX1_COMMAND_Type EX1_Command
#define EX1_COMMAND_section ".sy.x1cm"
#define EX1_COMMAND_marker x1cm
#include "symbol_set.define.h"
#define EX1_COMMAND_DEF(N,desc) \
void ex1cmd_##N(EX1_Ctx *ctx); \
SyDefine(EX1_COMMAND, N) = { #N, desc, ex1cmd_##N };\
void ex1cmd_##N(EX1_Ctx *ctx)
#endif /* EXAMPLE1_H */

View File

@ -1,35 +0,0 @@
/****** Define One Symbol Set *******/
#if 0
/* To define a symbol set, copy-paste the block below and then:
** Replace ZZZ with a name for the symbol set.
** Replace Typezz with the type of the symbol set.
** Replace secz with a unique name for the data section of the symbol set.
** IMPORTANT NOTE: you only get 4 characters for the section name if you
** want to port to Windows.
*/
#define SYMBOL_SET_DEFINE ZZZ
#define ZZZ_Type Typezz
#define ZZZ_section ".sy.secz"
#define ZZZ_marker secz
#include "symbol_set.define.h"
#endif
/****** Define One Symbol Set *******/
/****** Common Helpers For Defining Symbols *******/
#if 0
/* Defining a basic struct with a NAME */
#define ZZZ_DEF(N,...) SyDefine(ZZZ, NAME) = { ... }
/* Defining a basic struct without a name */
#define ZZZ_DEF(...) SyDefineNameless(ZZZ, NAME) = { ... }
#endif
/****** Common Helpers For Defining Symbols *******/

View File

@ -4,7 +4,7 @@
**
** No warranty implied; use at your own risk
**
** Read symbol_set.intro.h to get started.
** Read README to get started.
*/
#if SY__OS_WINDOWS

View File

@ -4,7 +4,7 @@
**
** No warranty implied; use at your own risk
**
** Read symbol_set.intro.h to get started.
** Read README to get started.
*/
#ifndef SYMBOL_SET_H

89
symbol_set.starter.h Normal file
View File

@ -0,0 +1,89 @@
/***********************************************************
** symbol_set - A public domain C modifier library
** by Allen Webster, "Mr. 4th", allenw@mr4th.com
**
** No warranty implied; use at your own risk
**
** Read README to get started.
*/
/****************************
*****************************
********** Setup **********
*****************************
****************************/
#if 0
/* In ever compilation unit, #include "symbol_set.h" once before using
** any symbol set features or defining a symbol set. */
#include "symbol_set.h"
/* In one compilation unit, #include "symbol_set.c" */
#include "symbol_set.c"
#endif
/******************************************
*******************************************
********** Define A Symbol Set **********
*******************************************
******************************************/
#if 0
/* To define a symbol set, copy-paste the block below and then:
** Replace ZZZ with a name for the symbol set.
** Replace Typezz with the type of the symbol set.
** Replace secz with a unique name for the data section of the symbol set.
** IMPORTANT NOTE: only use 4 characters for the section name if you
** want to port to Windows.
*/
#define SYMBOL_SET_DEFINE ZZZ
#define ZZZ_Type Typezz
#define ZZZ_section ".sy.secz"
#define ZZZ_marker secz
#include "symbol_set.define.h"
#endif
/****************************************************
*****************************************************
********** Common Symbol Defining Macros **********
*****************************************************
****************************************************/
#if 0
/* Define a basic struct with a NAME */
#define ZZZ_DEF(N,...) SyDefine(ZZZ, NAME) = { ... }
/* Define a basic struct without a name */
#define ZZZ_DEF(...) SyDefineUnnamed(ZZZ, NAME) = { ... }
/* Define a struct with a NAME & attach a function.
** Replace zzzprefix with a unique function prefix.
** Update the parameter and return types as needed.
*/
#define ZZZ_DEF(N,...) \
void zzzprefix_##N(void); \
SyDefine(ZZZ, NAME) = { ..., zzzprefix_##N }; \
void zzzprefix_##N(void)
/* Define a struct with a NAME & attach multiple functions
** Replace zzzprefix1... with unique function prefixes.
** Update the parameter and return types as needed.
** Replace ZZZ_PREFIX1... with appropriate names.
*/
#define ZZZ_DEF(N,...) \
void zzzprefix1_##N(void); \
void zzzprefix2_##N(void); \
SyDefine(ZZZ, NAME) = { ..., zzzprefix1_##N, zzzprefix2_##N }
#define ZZZ_PREFIX1(N) void zzzprefix1_##N(void)
#define ZZZ_PREFIX2(N) void zzzprefix2_##N(void)
#endif

View File

@ -1,73 +0,0 @@
Example Writing:
[ ] Think up better introductory examples
[ ] Example of symbol sets with instances that don't need names
[ ] Example of more complex data initialization via the hook
[ ] Example of symbol set reuse across multiple programs
- Metaprogramming without needing input
Research and Provide Practical Use Tips:
[ ] See the symbol set in the debugger
[ ] Best ideas for solving serialization systems problem
[ ] Shader management
[ ] IDs for profiler blocks
[ ] How does this hold up when multiple DLLs or SOs are involved?
Vetting:
Compilers: CL, GCC, CLANG
Linkers: LINK, GCC, CLANG
OSs: Win32, Linux, Mac
(COFF) (ELF) (MACHO)
[ ] Check configurations for accurate section virtual sizes
Win32{
link: -INCREMENTAL:NO
clang (as linker): -Xlinker -INCREMENTAL:NO
All combinations of CL, LINK, CLANG work so far so long as the above
options are used.
}
Linux{ [ ] GCC CLANG [ ] GCC GCC [ ] CLANG GCC [ ] CLANG CLANG }
Mac { [ ] CLANG CLANG }
[ ] Check configurations for link time optimization removal of symbols
[ ] Vet __ImageBase trick on Windows linkers
Development:
[x] experiment with __ImageBase pseudo variable (linker variable)
[ ] Small as possible binary parser for "selfimg" purposes
[x] PE
[ ] Elf
[ ] Macho
"Mark II":
[ ] Object file editing for improved memory layout & symbol id references
[ ] Setup count and base pointer symbols
[ ] Learn how to put the symbol data into .data and relink everything
[ ] Setup id symbols & editing to give them values
[ ] Eliminate the "raw" version of symbols
[ ] Do I want to maintain a pair of versions one with object file editing
and one without?
Other Upgrade Research:
[ ] Could Symbol Sets syntax be organized in such a way that it's just a
data section and type wrapped in a macro?
Support Tools:
[x] see data section size and layout info
[ ] see symbols in symbol sets from object files
[ ] size of types