Skip to content

Commit 93e2d04

Browse files
committed
progress on compiler
1 parent 27e5cf6 commit 93e2d04

File tree

5 files changed

+188
-10
lines changed

5 files changed

+188
-10
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ project(dlang)
33

44
set(CMAKE_CXX_STANDARD 17)
55

6-
add_executable(dlang main.cpp parse/lex.cpp parse/parse.cpp vm/operator.cpp vm/operator.hpp vm/value.cpp vm/value.hpp vm/rt_macro.cpp vm/rt_macro.hpp vm/gc.cpp vm/gc.hpp vm/reference.cpp vm/reference.hpp)
6+
add_executable(dlang main.cpp parse/lex.cpp parse/parse.cpp vm/operator.cpp vm/operator.hpp vm/value.cpp vm/value.hpp vm/rt_macro.cpp vm/rt_macro.hpp vm/gc.cpp vm/gc.hpp vm/reference.cpp vm/reference.hpp compile/bytecode.hpp compile/bytecode.cpp)

compile/bytecode.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// Created by tate on 01-05-20.
3+
//
4+
5+
#include <string>
6+
#include "bytecode.hpp"
7+
8+
// convert to text representation
9+
std::string compile_text(std::vector<Command> cmds)
10+
{
11+
std::string ret;
12+
for (Command& cmd : cmds) {
13+
if (cmd.is_lit())
14+
ret += cmd.to_text();
15+
}
16+
return ret;
17+
}
18+
19+
20+
// convert to compressed binary format
21+
// return number of bytes stored in ret
22+
std::size_t compile_bin(std::vector<Command>, char*& ret)
23+
{
24+
25+
}

compile/bytecode.hpp

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// Created by tate on 01-05-20.
3+
//
4+
5+
#ifndef DLANG_BYTECODE_HPP
6+
#define DLANG_BYTECODE_HPP
7+
8+
#include <string>
9+
#include <vector>
10+
11+
#include "command.hpp"
12+
13+
// convert to text representation
14+
std::string compile_text(std::vector<Command>);
15+
16+
17+
// convert to compressed binary format
18+
// return number of bytes stored in ret
19+
std::size_t compile_bin(std::vector<Command>, char*& ret);
20+
21+
22+
#endif //DLANG_BYTECODE_HPP

compile/command.hpp

+139-8
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,27 @@
55
#ifndef DLANG_COMMAND_HPP
66
#define DLANG_COMMAND_HPP
77

8-
#include <inttypes.h>
8+
#include <cinttypes>
9+
#include <cstdlib>
10+
#include <variant>
11+
#include <cstring>
12+
913

1014
class Command {
15+
public:
1116

1217
// mnemonic instruction
1318
enum OPCode : uint8_t {
1419

1520
// these go in lit header
16-
START_LIT_STRING,
21+
START_LIT_STRING = 0,
1722
START_LIT_MACRO,
1823
START_LIT_JSON,
1924
//END_LIT_STRING, // just use '\0'...
2025
END_LIT_MACRO,
21-
END_LIT_JSON,
26+
//END_LIT_JSON, // just use '\0'
27+
28+
END_LIT_SECTION,
2229

2330
// these can go in macro bodies
2431
I64_LIT, // push int literal onto stack (too small for header)
@@ -34,14 +41,138 @@ class Command {
3441
BUILTIN_OP, // operate on stack
3542
// arg: int16, builtin operator id
3643

37-
} instr;
44+
// begin fault table
45+
ID_NAME, // user-defined identifier name
46+
// arg: str
47+
ID_ID, // compiled identifier number
48+
// arg: int64
49+
FILE_NAME, // file path
50+
// arg: str
51+
DEST_POS, // location in compiled file
52+
// arg: int64
53+
SRC_POS, // original file position
54+
// arg: int64
55+
56+
} instr : 8;
57+
58+
std::variant<uint16_t, int64_t, double, std::string> arg;
59+
60+
enum ArgType {
61+
INT64, INT16, FLOAT, STRING, NO_ARG
62+
};
63+
64+
// used for generating bytecode text format for debugging
65+
inline std::string to_text() {
66+
switch (this->instr) {
67+
68+
// literal defs
69+
case OPCode::START_LIT_STRING:
70+
return "String: \"" + std::get<std::string>(this->arg) + "\"\n";
71+
case OPCode::START_LIT_JSON:
72+
return "JSON: " + std::get<std::string>(this->arg) + "\n";
73+
case OPCode::START_LIT_MACRO:
74+
return "Macro: (:\n";
75+
case OPCode::END_LIT_MACRO:
76+
return ")\n";
77+
case OPCode::END_LIT_SECTION:
78+
return "#### End Literal Section ####\n";
79+
80+
// indented bc must be within macro body
81+
case OPCode::I64_LIT:
82+
return "\tint64 " + std::to_string(std::get<int64_t>(this->arg));
83+
case OPCode::F64_LIT:
84+
return "\tdouble " + std::to_string(std::get<double>(this->arg));
85+
case OPCode::DECL_ID:
86+
return "\tlet " + std::to_string((uint64_t) std::get<int64_t>(this->arg));
87+
case OPCode::USE_ID:
88+
return "\tid $" + std::to_string((uint64_t) std::get<int64_t>(this->arg));
89+
case OPCode::USE_LIT:
90+
return "\tliteral #" + std::to_string((uint64_t) std::get<int64_t>(this->arg));
91+
case OPCode::BUILTIN_OP:
92+
// switch (std::get<int16_t>(this->arg)) { ... }
93+
return "\tOP #" + std::to_string((uint16_t) std::get<int16_t>(this->arg));
94+
95+
// dont care about fault table yet
96+
default:
97+
return "";
98+
}
99+
}
100+
101+
// check if it goes in literal header
102+
inline bool is_lit() const noexcept {
103+
return this->instr < OPCode::END_LIT_SECTION;
104+
}
105+
106+
inline ArgType arg_type() {
107+
switch (this->instr) {
108+
case OPCode::F64_LIT:
109+
return ArgType::FLOAT;
110+
case OPCode::I64_LIT: case OPCode::DECL_IDL: case OPCode::USE_ID: case OPCode::USE_LIT:
111+
case OPCode::ID_ID: case OPCode::SRC_POS: case OPCode::DEST_POS:
112+
return ArgType::INT64;
113+
case OPCode::BUILTIN_OP:
114+
return ArgType::INT16;
115+
case OPCode::START_LIT_STRING: case OPCode::START_LIT_JSON: case OPCode::ID_NAME: case OPCode::FILE_NAME:
116+
return ArgType::STRING;
117+
118+
default:
119+
return ArgType::NO_ARG;
120+
}
121+
}
38122

39-
union {
40-
uint64_t i64;
41-
uint16_t i16;
123+
// copies compiled instruction into ret
124+
// returns number of chars to read
125+
std::size_t compile(char*& ret) {
126+
ArgType t = arg_type();
127+
size_t s = 1;
128+
switch (t) {
129+
case ArgType::STRING: {
130+
auto &str = std::get<std::string>(this->arg);
131+
s += str.size() + 1;
132+
ret = (char *) realloc(ret, s);
133+
strncpy(ret, (char *) &this->instr, 1);
134+
strcpy(ret + 1, str.c_str()); // also copies the '\0'
135+
break;
136+
}
137+
case ArgType::INT16: {
138+
s += sizeof(uint16_t);
139+
ret = (char *) realloc(ret, s);
140+
uint16_t n = std::get<uint16_t>(this->arg);
141+
strncpy(ret, (char *) &this->instr, 1);
142+
strncpy(ret + 1, (char *) &n, sizeof(uint16_t));
143+
break;
144+
}
145+
case ArgType::INT64: {
146+
s += sizeof(int64_t);
147+
ret = (char *) realloc(ret, s);
148+
int64_t n = std::get<int64_t>(this->arg);
149+
strncpy(ret, (char *) &this->instr, 1);
150+
strncpy(ret + 1, (char *) &n, sizeof(int64_t));
151+
break;
152+
}
153+
case ArgType::FLOAT: {
154+
s += sizeof(double);
155+
ret = (char *) realloc(ret, s);
156+
double n = std::get<double>(this->arg);
157+
strncpy(ret, (char *) &this->instr, 1);
158+
strncpy(ret + 1, (char *) &n, sizeof(double));
159+
break;
160+
}
161+
case ArgType::NO_ARG: {
162+
ret = (char *) realloc(ret, s);
163+
strncpy(ret, (char *) &this->instr, 1);
164+
break;
165+
}
166+
default: {
167+
ret = (char *) realloc(ret, s);
168+
strncpy(ret, (char *) &this->instr, 1);
169+
break;
170+
}
171+
}
42172

173+
return s;
174+
}
43175

44-
} arg;
45176

46177
};
47178

vm/gc.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct gc_item {
2525
std::atomic<unsigned long> rc = 1;
2626
};
2727

28-
void* gc_mallloc(VM& vm, std::size_t size);
28+
void* gc_malloc(VM& vm, std::size_t size);
2929

3030

3131

0 commit comments

Comments
 (0)