-
-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The goal of this PR is to verify the system basically works, like evaluate a simple "ExprInt". Not all expressions have been supported yet.
- Loading branch information
Showing
62 changed files
with
1,569 additions
and
518 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#pragma once | ||
|
||
#include <cassert> | ||
#include <cstring> | ||
#include <string> | ||
#include <string_view> | ||
#include <type_traits> | ||
#include <vector> | ||
|
||
namespace bc { | ||
|
||
template <class T> void readBytecode(std::string_view &Data, T &Obj) { | ||
static_assert(!std::is_same_v<T, T>, | ||
"No readBytecode implementation for this type"); | ||
} | ||
|
||
/// \brief Basic primitives. Deocde from bytes by `memcpy`. | ||
template <class T> | ||
requires std::is_standard_layout_v<T> && std::is_trivial_v<T> | ||
void readBytecode(std::string_view &Data, T &Obj) { | ||
assert(Data.size() >= sizeof(T)); | ||
std::memcpy(&Obj, Data.begin(), sizeof(T)); | ||
Data = Data.substr(sizeof(T)); | ||
} | ||
|
||
template <class T> | ||
void readBytecode(std::string_view &Data, std::vector<T> &Obj) { | ||
size_t Size; | ||
readBytecode(Data, Size); | ||
Obj.resize(Size); | ||
for (auto &E : Obj) | ||
readBytecode(Data, E); | ||
} | ||
|
||
template <> | ||
void readBytecode<std::string>(std::string_view &Data, std::string &Obj); | ||
|
||
template <class T> T eat(std::string_view &Data) { | ||
T Obj; | ||
readBytecode(Data, Obj); | ||
return Obj; | ||
} | ||
|
||
} // namespace bc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#pragma once | ||
|
||
#include <ostream> | ||
#include <sstream> | ||
#include <type_traits> | ||
|
||
namespace bc { | ||
|
||
/// \brief Basic primitives. Trivial data types are just written to a stream. | ||
template <class T> | ||
requires std::is_standard_layout_v<T> && std::is_trivial_v<T> | ||
void writeBytecode(std::ostream &OS, const T &Data) { | ||
OS.write(reinterpret_cast<const char *>(&Data), sizeof(T)); | ||
} | ||
|
||
void writeBytecode(std::ostream &OS, const std::string_view &Data); | ||
|
||
inline void writeBytecode(std::ostream &OS, const std::string &Data) { | ||
writeBytecode(OS, std::string_view(Data)); | ||
} | ||
|
||
template <class T> std::string toBytecode(const T &Data) { | ||
std::ostringstream OS; | ||
writeBytecode(OS, Data); | ||
return OS.str(); | ||
} | ||
|
||
} // namespace bc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
libbc_inc = include_directories('include') | ||
|
||
libbc_lib = library( | ||
'bc', | ||
'src/Read.cpp', | ||
'src/Write.cpp', | ||
include_directories: libbc_inc, | ||
) | ||
|
||
libbc = declare_dependency( | ||
include_directories: libbc_inc, | ||
link_with: libbc_lib, | ||
) | ||
|
||
install_subdir('include/bc', install_dir: 'include') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#include "bc/Read.h" | ||
|
||
namespace bc { | ||
|
||
template <> | ||
void readBytecode<std::string>(std::string_view &Data, std::string &Obj) { | ||
size_t Size; | ||
readBytecode(Data, Size); | ||
Obj.resize(Size); | ||
std::memcpy(Obj.data(), Data.data(), Size); | ||
Data = Data.substr(Size); | ||
} | ||
|
||
} // namespace bc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#include "bc/Write.h" | ||
|
||
namespace bc { | ||
|
||
void writeBytecode(std::ostream &OS, const std::string_view &Data) { | ||
writeBytecode(OS, static_cast<std::size_t>(Data.size())); | ||
OS.write(Data.data(), static_cast<std::streamsize>(Data.size())); | ||
} | ||
|
||
} // namespace bc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# libnixbc | ||
|
||
Defines general bytecode for nix AST. | ||
This is used for nix-interop, with C++ evaluator, thus the node definition is targeted for C++ types. | ||
|
||
|
||
## The format | ||
|
||
|
||
All AST nodes are encoded in a compact binary format. | ||
The entire AST is serialized into into a form similar to [S-expression](https://en.wikipedia.org/wiki/S-expression). | ||
|
||
|
||
### Node Format | ||
|
||
| Field Name | Byte Size | ||
|:-:|:-:| | ||
| Pointer | Pointer Size | ||
| Kind | 4 | ||
| Payloads | N/A |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#pragma once | ||
|
||
#include "Origin.h" | ||
|
||
#include <cstdint> | ||
|
||
namespace nixbc { | ||
|
||
struct FileHeader { | ||
static constexpr int MagicValue = 0x72A17086; | ||
uint32_t Magic; | ||
uint32_t Version; | ||
/* Origin */ | ||
}; | ||
|
||
} // namespace nixbc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#pragma once | ||
|
||
#include <cstdint> | ||
|
||
namespace nixbc { | ||
|
||
enum ExprKind : int32_t { | ||
EK_Assert, | ||
EK_Attrs, | ||
EK_Call, | ||
EK_ConcatStrings, | ||
EK_Float, | ||
EK_If, | ||
EK_Int, | ||
EK_Lambda, | ||
EK_Let, | ||
EK_List, | ||
EK_OpAnd, | ||
EK_OpConcatLists, | ||
EK_OpEq, | ||
EK_OpHasAttr, | ||
EK_OpImpl, | ||
EK_OpNEq, | ||
EK_OpNot, | ||
EK_OpOr, | ||
EK_OpUpdate, | ||
EK_Path, | ||
EK_Pos, | ||
EK_Select, | ||
EK_String, | ||
EK_Var, | ||
EK_With, | ||
}; | ||
|
||
struct NodeHeader { | ||
ExprKind Kind; | ||
uintptr_t Handle; | ||
}; | ||
|
||
} // namespace nixbc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#pragma once | ||
|
||
#include <bc/Read.h> | ||
|
||
#include <cstdint> | ||
#include <string> | ||
|
||
namespace nixbc { | ||
|
||
class Origin { | ||
public: | ||
/// \brief Origin kind. | ||
/// | ||
/// \note Nix interpreter may read the file, or try to read source code for | ||
/// diagnostics reporting. | ||
enum OriginKind : uint8_t { | ||
/// None. | ||
OK_None, | ||
|
||
/// Standard input. | ||
OK_Stdin, | ||
|
||
/// \p EvalState::parseExprFromString() | ||
OK_String, | ||
|
||
/// \p EvalState::parseExprFromFile() | ||
OK_Path, | ||
}; | ||
|
||
private: | ||
OriginKind Kind; | ||
|
||
protected: | ||
Origin(OriginKind Kind) : Kind(Kind) {} | ||
|
||
public: | ||
[[nodiscard]] OriginKind kind() const { return Kind; } | ||
}; | ||
|
||
void readBytecode(std::string_view &Data, Origin &Obj); | ||
void writeBytecode(std::ostream &OS, const Origin &O); | ||
|
||
class OriginPath : public Origin { | ||
std::string Path; | ||
|
||
public: | ||
OriginPath() : Origin(OK_Path) {} | ||
|
||
[[nodiscard]] std::string &path() { return Path; } | ||
[[nodiscard]] const std::string &path() const { return Path; } | ||
}; | ||
|
||
void readBytecode(std::string_view &Data, OriginPath &Obj); | ||
void writeBytecode(std::ostream &OS, const OriginPath &O); | ||
|
||
} // namespace nixbc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#pragma once | ||
|
||
#include <cstdint> | ||
|
||
namespace nixbc { | ||
|
||
using NixInt = int64_t; | ||
using NixFloat = double; | ||
using PosInt = uint32_t; | ||
|
||
} // namespace nixbc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
libnixbc_deps = [ libbc ] | ||
libnixbc_inc = include_directories('include') | ||
|
||
libnixbc_lib = library( | ||
'nixbc', | ||
'src/Origin.cpp', | ||
include_directories: libnixbc_inc, | ||
dependencies: libnixbc_deps, | ||
) | ||
|
||
libnixbc = declare_dependency( | ||
include_directories: libnixbc_inc, | ||
link_with: libnixbc_lib, | ||
dependencies: libnixbc_deps, | ||
) | ||
|
||
install_subdir('include/nixbc', install_dir: 'include') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#include "nixbc/Origin.h" | ||
|
||
#include <cassert> | ||
|
||
namespace nixbc { | ||
|
||
void readBytecode(std::string_view &Data, Origin &Obj) {} | ||
|
||
void writeBytecode(std::ostream &OS, const Origin &O) {} | ||
|
||
void readBytecode(std::string_view &Data, OriginPath &Obj) {} | ||
|
||
void writeBytecode(std::ostream &OS, const OriginPath &O) {} | ||
|
||
} // namespace nixbc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/// \file | ||
/// \brief Serialization of nixf nodes. | ||
/// | ||
/// Serialization is the process of converting nix nodes into a byte stream. The | ||
/// target format is "nixbc". | ||
|
||
#pragma once | ||
|
||
#include "nixf/Basic/Nodes.h" | ||
|
||
#include <cstdint> | ||
|
||
namespace nixf { | ||
|
||
void writeBytecode(std::ostream &OS, const Node &N); | ||
|
||
} // namespace nixf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#include "Write.h" | ||
|
||
#include <bc/Write.h> | ||
|
||
#include <nixbc/Nodes.h> | ||
|
||
namespace nixf { | ||
|
||
using namespace nixbc; | ||
|
||
using bc::writeBytecode; | ||
|
||
void writeBytecode(std::ostream &OS, const ExprInt &N) { | ||
writeBytecode(OS, NodeHeader{EK_Int, reinterpret_cast<std::uintptr_t>(&N)}); | ||
writeBytecode(OS, N.value()); | ||
} | ||
|
||
void writeBytecode(std::ostream &OS, const ExprBinOp &N) { | ||
using namespace tok; | ||
|
||
if (!N.lhs() || !N.rhs()) // Skip invalid nodes | ||
return; | ||
|
||
const Expr &LHS = *N.lhs(); | ||
const Expr &RHS = *N.rhs(); | ||
|
||
switch (N.op().op()) { | ||
case tok_op_add: | ||
// (+ a b) -> (ConcatStrings a b) | ||
writeBytecode( | ||
OS, NodeHeader{EK_ConcatStrings, reinterpret_cast<std::uintptr_t>(&N)}); | ||
writeBytecode(OS, static_cast<const Node &>(LHS)); | ||
writeBytecode(OS, static_cast<const Node &>(RHS)); | ||
return; | ||
default: | ||
break; | ||
} | ||
assert(false && "Unhandled binary operator"); | ||
__builtin_unreachable(); | ||
} | ||
|
||
void writeBytecode(std::ostream &OS, const Node &N) { | ||
switch (N.kind()) { | ||
case Node::NK_ExprInt: | ||
writeBytecode(OS, static_cast<const ExprInt &>(N)); | ||
break; | ||
case Node::NK_ExprBinOp: | ||
writeBytecode(OS, static_cast<const ExprBinOp &>(N)); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
} // namespace nixf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#include "nixf/Bytecode/Write.h" | ||
|
||
#include <nixbc/Nodes.h> | ||
|
||
namespace nixf { | ||
|
||
void writeBytecode(std::ostream &OS, const ExprInt &N); | ||
|
||
void writeBytecode(std::ostream &OS, const ExprBinOp &N); | ||
|
||
} // namespace nixf |
Oops, something went wrong.