From 81cab430b58b75fe0a6c75722908481dd4d9d55a Mon Sep 17 00:00:00 2001 From: rtk0c Date: Wed, 15 Oct 2025 20:31:31 +0000 Subject: Move imported files into metafang/ dir this metaprogramming attempt was started outside, and then imported here 5124eb80701523ac16928219e9a1031eded128ef..bc8c20d1e93b5c18e8915d356e74024092a74ce8 --- metafang/cm.lua | 40 ++++++++++++++++++++++++++++++++++++++++ metafang/cm/ex01.lua | 27 +++++++++++++++++++++++++++ metafang/cm/ex02.decl | 22 ++++++++++++++++++++++ metafang/cm/ex03.cm | 42 ++++++++++++++++++++++++++++++++++++++++++ metafang/cm_decl_parse.lua | 0 metafang/plan.txt | 0 metafang/tablgen.lua | 15 +++++++++++++++ 7 files changed, 146 insertions(+) create mode 100644 metafang/cm.lua create mode 100644 metafang/cm/ex01.lua create mode 100644 metafang/cm/ex02.decl create mode 100644 metafang/cm/ex03.cm create mode 100644 metafang/cm_decl_parse.lua create mode 100644 metafang/plan.txt create mode 100644 metafang/tablgen.lua (limited to 'metafang') diff --git a/metafang/cm.lua b/metafang/cm.lua new file mode 100644 index 0000000..e2d11f6 --- /dev/null +++ b/metafang/cm.lua @@ -0,0 +1,40 @@ +-- Cm: name inspired by "C meta(language)", but it's not really a metalangauge (whatever this means) of C (or anything else) + +local function LateResolveType(name) + -- "lb" - Lazy Binding + return {_tag = "lb", _lb_typename = name} +end + +local function TypeTagger(tag) + return function(props) + props._tag = tag + return props + end +end + +local cm_env_fns = { + _namespace = 0, -- TODO + _t = LateResolveType, + _struct = TypeTagger("struct"), + _union = TypeTagger("union"), + _alias = TypeTagger("alias"), +} +local cm_env_metatable = {__index = cm_env_fns} + +---@param fn function +---@return table +function LoadCmLua(fn) + local env = {} + setmetatable(env, cm_env_metatable) + + local old_fenv = getfenv(fn) + setfenv(fn, env) + pcall(fn) + setfenv(fn, old_fenv) + + return env +end + +function LoadCmDecl(src) + -- TODO +end diff --git a/metafang/cm/ex01.lua b/metafang/cm/ex01.lua new file mode 100644 index 0000000..f92ec2a --- /dev/null +++ b/metafang/cm/ex01.lua @@ -0,0 +1,27 @@ +-- Environment is loaded with the utils (as metatable.__index) +-- Global vars (aka properties on env) will be read as decls + +-- TERMINOLOGY: +-- decl: a property somewhere, the property name and the value makes up the declaration +-- type: a value (perhaps a part of a decl), which contains a type tag ("struct", "union", "alias", etc.) and extra info for that kind of type + +-- _struct, _union, _alias, etc. are type construction helpers. +-- They take the essential info, and returns a value properly decorated. For example it might just add a property {_tag="struct"}, or perhaps more. + +-- name implied by property key here +Bar = _struct({ + -- _t: Loads another type by its name. Return the type, or a placeholder if the type is not yet available + -- Useful recursive definitions + -- Undefined type errors generated on the referential resolution pass (i.e. not immediately) + field1 = _t("i32"), + field2 = _t("string"), + -- Deferred loading as described above + compound_field = _t("Foo"), +}) + +uint32 = _alias(_t("u32")) + +-- Note, defined after Bar! +Foo = _struct({ + n = _t("i32"), +}) diff --git a/metafang/cm/ex02.decl b/metafang/cm/ex02.decl new file mode 100644 index 0000000..d695e33 --- /dev/null +++ b/metafang/cm/ex02.decl @@ -0,0 +1,22 @@ +// Declarations only version of Cm (like mojo/protobuf? not sure) + +// assume special receiver (as opposed to smalltalk/objC style message passing) +// -- actually, on second thought, this has nothing to do with dispatching (and smalltalk is single dispatch) +// -- (no touching multiple dispatch since that's equivalent to reinventing a new language) +// overloading discouraged, because runtime has to do extra work dispatching +// declare functions outside, with `this` keyword marking receiver +// - in C, func -> prefixed with reciever type, 1st arg is reciever pointer +// - in C++, func -> member function +// - lua (or whatever else), reciever type correspondingly + +Foo { + data +} + +// C: mangling +// C++: overloading +// Lua: generate binding with type detection based dispatcher +fn some_function(this: Foo, arg: i32) +fn some_function(this: Foo) + +// alternative: use S-expression, get rid of parsing step? diff --git a/metafang/cm/ex03.cm b/metafang/cm/ex03.cm new file mode 100644 index 0000000..417799f --- /dev/null +++ b/metafang/cm/ex03.cm @@ -0,0 +1,42 @@ +// Hypothetical, fully ledged version of Cm, at compile time, using a superset of the runtime language +// with macros, and an escape hatch into native code (C or whatever) + +// Language structurally, a bit like Nim: +// - the scripting language itself +// - macros, which are functions from language itself operating on special AST values at compile time +// - (NEW) native escape hatch, kind of literate programming style, expanding into native program source code at compile time + +// So the compile procedure is as follows: +// - build interpreter (native source code) from source +// - init interpreter +// - load program source code, evaluate to produce +// - an environment image (bytecode of scripting constructs), and +// - native program source (text of things produced by native escape hatch, plus interpreter source code itself, plus auto generated bindings) +// - build native program +// And run procedure is: +// - init interpreter (<- the PE/mach-o/ELF entrypoint here) +// - init native program parts (<- i.e. the escape hatches don't generate an actual main() func, instead a customly named init() func that gets called by the generated machinery) +// - load bindings +// - load environment image +// - run native program entrypoint +// The order of native program entrypoint vs. environment loading might be reversed. Depending on how it makes sense. +// Or maybe there will be 2 parts, the native program *init* and *start*. Former would be like the _mainCRTStartup() that initializes global variables, etc. + +// REQUIREMENT FOR NATIVE PROGRAM SOURCE: +// Must be nicely readable. +// We plan on completely reusing the traditional native program debuggers, e.g. GDB for debugging +// The interpreter can then have its own debugging system +// Problem: How to do mixed language debugging? like stepping into a native function, this is a lot of work/hacks to wrap on top of e.g. GDB +// SIDE THOUGHT: +// should bindings be baked into the environment image (i.e. design the bytecode format to include this? however it should be done; can't really imagine it now?) +// or should they be generated e.g. `bind_function("func_name", &func_written_in_C);`? + +// REUSING EXSITING SCRIPTING LANGUAGE +// We don't want to reimplement a language from scratch +// Hacking e.g. PUC-Lua's parser? Kind of like Terra + +// terminology akin to Janet (from _Janet for Mortals_): +// compile: evaluating the program sources to produce an environment +// runtime: evaluating the environment + + diff --git a/metafang/cm_decl_parse.lua b/metafang/cm_decl_parse.lua new file mode 100644 index 0000000..e69de29 diff --git a/metafang/plan.txt b/metafang/plan.txt new file mode 100644 index 0000000..e69de29 diff --git a/metafang/tablgen.lua b/metafang/tablgen.lua new file mode 100644 index 0000000..3cef364 --- /dev/null +++ b/metafang/tablgen.lua @@ -0,0 +1,15 @@ +local F = {} + +local function tostrType(t) +end + +--- Output the given text as-is to the generated file. +function F:Write(chunk) + -- TODO + +end + +function F:WriteFuncDecl(func_name, ret, arg) + -- Write to output as a C function declaration + -- TODO +end -- cgit v1.3.1