diff --git a/src/irc/types.h b/src/irc/types.h index 7b0765d..7a4c754 100644 --- a/src/irc/types.h +++ b/src/irc/types.h @@ -13,7 +13,7 @@ namespace nix_irc { constexpr uint32_t IR_MAGIC = 0x4E495258; -constexpr uint32_t IR_VERSION = 2; +constexpr uint32_t IR_VERSION = 3; enum class NodeType : uint8_t { CONST_INT = 0x01, @@ -41,6 +41,11 @@ enum class NodeType : uint8_t { ASSERT = 0x52, THUNK = 0x60, FORCE = 0x61, + LAMBDA_PATTERN = 0x70, + INHERIT = 0x71, + INHERIT_FROM = 0x72, + STRING_INTERPOLATION = 0x73, + BUILTIN_CALL = 0x74, ERROR = 0xFF }; @@ -131,6 +136,25 @@ struct LambdaNode { LambdaNode(uint32_t a, std::shared_ptr b, uint32_t l = 0); }; +struct PatternField { + std::string name; + std::optional> default_value; + + PatternField(std::string n, std::optional> def = std::nullopt) + : name(std::move(n)), default_value(std::move(def)) {} +}; + +struct LambdaPatternNode { + std::vector required_fields; + std::vector optional_fields; + std::optional at_binding; + bool allow_extra; + std::shared_ptr body; + uint32_t line = 0; + + LambdaPatternNode(std::shared_ptr b, uint32_t l = 0); +}; + struct AppNode { std::shared_ptr func; std::shared_ptr arg; @@ -252,14 +276,70 @@ struct ListNode { : elements(std::move(elems)), line(l) {} }; +struct InheritNode { + std::vector names; + uint32_t line = 0; + + InheritNode(std::vector n = {}, uint32_t l = 0) : names(std::move(n)), line(l) {} +}; + +struct InheritFromNode { + std::shared_ptr source; + std::vector names; + uint32_t line = 0; + + InheritFromNode(std::shared_ptr src, std::vector n, uint32_t l = 0) + : source(std::move(src)), names(std::move(n)), line(l) {} +}; + +struct StringPart { + enum class Type { LITERAL, EXPR }; + Type type; + std::string literal; + std::shared_ptr expr; + + static StringPart make_literal(std::string lit) { + StringPart part; + part.type = Type::LITERAL; + part.literal = std::move(lit); + return part; + } + + static StringPart make_expr(std::shared_ptr e) { + StringPart part; + part.type = Type::EXPR; + part.expr = std::move(e); + return part; + } +}; + +struct StringInterpolationNode { + std::vector parts; + uint32_t line = 0; + + StringInterpolationNode(std::vector p = {}, uint32_t l = 0) + : parts(std::move(p)), line(l) {} +}; + +struct BuiltinCallNode { + std::string builtin_name; + std::vector> args; + uint32_t line = 0; + + BuiltinCallNode(std::string name, std::vector> a = {}, uint32_t l = 0) + : builtin_name(std::move(name)), args(std::move(a)), line(l) {} +}; + // Node wraps a variant for type-safe AST class Node { public: - using Variant = std::variant; + using Variant = + std::variant; Variant data; @@ -312,6 +392,9 @@ inline ThunkNode::ThunkNode(std::shared_ptr e, uint32_t l) : expr(std::mov inline ForceNode::ForceNode(std::shared_ptr e, uint32_t l) : expr(std::move(e)), line(l) {} +inline LambdaPatternNode::LambdaPatternNode(std::shared_ptr b, uint32_t l) + : allow_extra(false), body(std::move(b)), line(l) {} + struct SourceFile { std::string path; std::string content;