feat: DSL parser, eval system, and project structure
- Hand-written lexer + recursive-descent parser for .kap package definitions
- Package constructs: const, license, provides, outputs, patches, depends
(version-constrained, feature-gated, output-targeted), features (enabled/
forced/flag), config files (default/replace/merge with cfg interpolation),
env (?= soft-set), prepare/build/check/install phases
- Evaluator: recursive resolver for prefix, jobopts, destdir, userargs,
cfg.*, feature.*, package vars
- Comments: // single-line, /* */ multi-line
- /kappa/{bin,temp,db,system,system/builds} path layout
- Clang 22, C++23, CMake + vcpkg (tomlplusplus)
- .clangd + .clang-tidy configured
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace kappa::dsl {
|
||||
|
||||
using Command = std::string;
|
||||
|
||||
struct Phase {
|
||||
std::vector<Command> commands;
|
||||
};
|
||||
|
||||
struct Dependency {
|
||||
std::string name;
|
||||
std::string version;
|
||||
std::string output;
|
||||
std::string feature; // empty = unconditional
|
||||
};
|
||||
|
||||
struct ConfigFile {
|
||||
std::string path;
|
||||
std::string mode;
|
||||
std::unordered_map<std::string, std::string> entries;
|
||||
};
|
||||
|
||||
struct FeatureDef {
|
||||
bool enabled = false;
|
||||
bool force = false;
|
||||
std::string flag;
|
||||
};
|
||||
|
||||
struct Patch {
|
||||
std::string url;
|
||||
std::string sha256;
|
||||
int level = 1;
|
||||
};
|
||||
|
||||
struct EnvEntry {
|
||||
std::string key;
|
||||
std::string value;
|
||||
bool soft = false;
|
||||
};
|
||||
|
||||
struct PackageDef {
|
||||
std::string name;
|
||||
std::string version;
|
||||
std::string source;
|
||||
std::string license;
|
||||
std::vector<Dependency> depends;
|
||||
std::vector<std::string> provides;
|
||||
std::vector<std::string> outputs;
|
||||
std::unordered_map<std::string, FeatureDef> features;
|
||||
std::vector<ConfigFile> config_files;
|
||||
std::vector<Patch> patches;
|
||||
std::vector<EnvEntry> env_entries;
|
||||
std::unordered_set<std::string> const_keys;
|
||||
Phase prepare;
|
||||
Phase build;
|
||||
Phase check;
|
||||
Phase install;
|
||||
};
|
||||
|
||||
} // namespace kappa::dsl
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "kappa/dsl/token.hpp"
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace kappa::dsl {
|
||||
|
||||
class Lexer {
|
||||
public:
|
||||
explicit Lexer(std::string_view source);
|
||||
|
||||
Token next();
|
||||
|
||||
private:
|
||||
Token scan_ident();
|
||||
Token scan_string();
|
||||
Token scan_symbol();
|
||||
void skip_whitespace();
|
||||
bool skip_comment();
|
||||
|
||||
char peek() const;
|
||||
char advance();
|
||||
bool match(char c);
|
||||
|
||||
std::string_view source_;
|
||||
std::size_t pos_ = 0;
|
||||
int line_ = 1;
|
||||
int col_ = 1;
|
||||
int token_start_line_ = 0;
|
||||
int token_start_col_ = 0;
|
||||
};
|
||||
|
||||
} // namespace kappa::dsl
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "kappa/dsl/ast.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace kappa::dsl {
|
||||
|
||||
PackageDef parse(std::string_view source);
|
||||
|
||||
} // namespace kappa::dsl
|
||||
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace kappa::dsl {
|
||||
|
||||
enum class TokenType {
|
||||
Eof,
|
||||
Newline,
|
||||
|
||||
// Symbols
|
||||
Lbrace, // {
|
||||
Rbrace, // }
|
||||
Equals, // =
|
||||
Lbracket, // [
|
||||
Rbracket, // ]
|
||||
Comma, // ,
|
||||
|
||||
// Literals
|
||||
String, // "..."
|
||||
Ident, // bare word (keyword, command, variable ref)
|
||||
|
||||
// Keywords (tokenised as Ident, then classified)
|
||||
KwPackage,
|
||||
KwVersion,
|
||||
KwSource,
|
||||
KwDepends,
|
||||
KwProvides,
|
||||
KwOutputs,
|
||||
KwFeatures,
|
||||
KwConfig,
|
||||
KwConst,
|
||||
KwLicense,
|
||||
KwPatches,
|
||||
KwEnv,
|
||||
KwPrepare,
|
||||
KwBuild,
|
||||
KwCheck,
|
||||
KwInstall,
|
||||
KwTrue,
|
||||
KwFalse,
|
||||
};
|
||||
|
||||
struct Token {
|
||||
TokenType type = TokenType::Eof;
|
||||
std::string lexeme;
|
||||
int line = 0;
|
||||
int col = 0;
|
||||
};
|
||||
|
||||
std::string_view token_name(TokenType type);
|
||||
|
||||
} // namespace kappa::dsl
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "kappa/dsl/ast.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace kappa::eval {
|
||||
|
||||
enum class VarKind {
|
||||
Unknown,
|
||||
Builtin, // ${prefix}, ${jobs}, ${jobopts}, ${userargs}
|
||||
Package, // ${version}, ${name}, ${source}
|
||||
Config, // ${cfg.key}
|
||||
Feature, // ${feature.key} → expanded flag or ""
|
||||
};
|
||||
|
||||
struct ResolvedVar {
|
||||
std::string value;
|
||||
VarKind kind = VarKind::Unknown;
|
||||
};
|
||||
|
||||
struct Scope {
|
||||
std::unordered_map<std::string, std::string> builtins;
|
||||
std::unordered_map<std::string, std::string> config;
|
||||
std::unordered_map<std::string, dsl::FeatureDef> features;
|
||||
std::unordered_map<std::string, std::string> package;
|
||||
};
|
||||
|
||||
Scope make_default_scope();
|
||||
|
||||
ResolvedVar resolve(std::string_view name, const Scope& scope);
|
||||
|
||||
std::string interpolate(std::string_view input, const Scope& scope);
|
||||
|
||||
} // namespace kappa::eval
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace kappa {
|
||||
|
||||
struct PackageConfig {
|
||||
std::string name;
|
||||
std::string version;
|
||||
std::string description;
|
||||
std::string source_url;
|
||||
std::string source_extension;
|
||||
std::string source_hash;
|
||||
std::vector<std::string> dependencies;
|
||||
std::string build_system;
|
||||
};
|
||||
|
||||
PackageConfig parse_package(const std::string& toml_path);
|
||||
void print_package(std::ostream& os, const PackageConfig& pkg);
|
||||
|
||||
} // namespace kappa
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace kappa::paths {
|
||||
|
||||
inline const std::filesystem::path root{"/kappa"};
|
||||
inline const auto bin_dir = root / "bin";
|
||||
inline const auto temp_dir = root / "temp";
|
||||
inline const auto db_dir = root / "db";
|
||||
inline const auto system_dir = root / "system";
|
||||
inline const auto builds_dir = system_dir / "builds";
|
||||
|
||||
void ensure_directories();
|
||||
|
||||
} // namespace kappa::paths
|
||||
Reference in New Issue
Block a user