Expose the source location class to the compiler/vm

This commit is contained in:
Konstantin Nazarov 2024-09-05 23:22:45 +01:00
parent c194a34efb
commit aa1d8d7fa9
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
11 changed files with 155 additions and 17 deletions

View file

@ -69,6 +69,8 @@ Result<PodObject*> Arena::gc_pod(PodObject* obj) {
return gc_string((PodString*)obj);
case Tag::Symbol:
return gc_symbol((PodSymbol*)obj);
case Tag::SrcLoc:
return gc_srcloc((PodSrcLoc*)obj);
case Tag::Syntax:
return gc_syntax((PodSyntax*)obj);
case Tag::Pair:
@ -137,13 +139,23 @@ Result<PodObject*> Arena::gc_symbol(PodSymbol* obj) {
return nobj;
}
Result<PodObject*> Arena::gc_srcloc(PodSrcLoc* obj) {
auto nobj = TRY(alloc<PodSrcLoc>());
nobj->header.tag = Tag::SrcLoc;
nobj->sourcerange = obj->sourcerange;
return nobj;
}
Result<PodObject*> Arena::gc_syntax(PodSyntax* obj) {
auto nobj = TRY(alloc<PodSyntax>());
nobj->header.tag = Tag::Syntax;
nobj->filename = TRY(gc_pod(obj->filename.get()));
nobj->sourcerange = obj->sourcerange;
nobj->srcloc = TRY(gc_pod(obj->srcloc.get()));
nobj->expression = TRY(gc_pod(obj->expression.get()));
return nobj;

View file

@ -149,6 +149,7 @@ class Arena {
Result<PodObject*> gc_float(PodFloat* obj);
Result<PodObject*> gc_string(PodString* obj);
Result<PodObject*> gc_symbol(PodSymbol* obj);
Result<PodObject*> gc_srcloc(PodSrcLoc* obj);
Result<PodObject*> gc_syntax(PodSyntax* obj);
Result<PodObject*> gc_pair(PodPair* obj);
Result<PodObject*> gc_array(PodArray* obj);

View file

@ -28,6 +28,8 @@ Result<Value> Value::create(PodObject* obj) {
return Value(TRY(String::create((PodString*)obj)));
case Tag::Symbol:
return Value(TRY(Symbol::create((PodSymbol*)obj)));
case Tag::SrcLoc:
return Value(TRY(SrcLoc::create((PodSrcLoc*)obj)));
case Tag::Syntax:
return Value(TRY(Syntax::create((PodSyntax*)obj)));
case Tag::Pair:
@ -77,15 +79,12 @@ Result<ByteArray> ByteArray::create(const String& str) {
return ByteArray(TRY(MkGcRoot(pod)));
}
Result<Syntax> Syntax::create(String filename, SourceRange sourcerange,
Value expression) {
auto pod = TRY(arena_alloc<PodSyntax>());
pod->header.tag = Tag::Syntax;
pod->filename = filename.pod();
Result<SrcLoc> SrcLoc::create(const SourceRange& sourcerange) {
auto pod = TRY(arena_alloc<PodSrcLoc>());
pod->header.tag = Tag::SrcLoc;
pod->sourcerange = sourcerange;
pod->expression = expression.pod();
return Syntax(TRY(MkGcRoot(pod)));
return SrcLoc(TRY(MkGcRoot(pod)));
}
short sourceposition_cmp(const SourcePosition& lhs, const SourcePosition& rhs) {
@ -103,11 +102,32 @@ short sourcerange_cmp(const SourceRange& lhs, const SourceRange rhs) {
return sourceposition_cmp(lhs.end, rhs.end);
}
SourceRange SrcLoc::sourcerange() const { return _value->sourcerange; }
Result<short> SrcLoc::cmp(const SrcLoc& rhs) const {
auto lhs_sourcerange = sourcerange();
auto rhs_sourcerange = rhs.sourcerange();
return sourcerange_cmp(lhs_sourcerange, rhs_sourcerange);
}
Result<Syntax> Syntax::create(String filename, SrcLoc srcloc,
Value expression) {
auto pod = TRY(arena_alloc<PodSyntax>());
pod->header.tag = Tag::Syntax;
pod->filename = filename.pod();
pod->srcloc = srcloc.pod();
pod->expression = expression.pod();
return Syntax(TRY(MkGcRoot(pod)));
}
Result<Value> Syntax::filename() const {
return Value::create(_value->filename.get());
}
SourceRange Syntax::sourcerange() const { return _value->sourcerange; }
Result<Value> Syntax::srcloc() const {
return Value::create(_value->srcloc.get());
}
Result<Value> Syntax::expression() const {
return Value::create(_value->expression.get());
@ -119,10 +139,10 @@ Result<short> Syntax::cmp(const Syntax& rhs) const {
short res = TRY(lhs_filename.cmp(rhs_filename));
if (res != 0) return res;
auto lhs_sourcerange = sourcerange();
auto rhs_sourcerange = rhs.sourcerange();
res = sourcerange_cmp(lhs_sourcerange, rhs_sourcerange);
if (res != 0) return res;
auto lhs_srcloc = TRY(srcloc());
auto rhs_srcloc = TRY(rhs.srcloc());
res = TRY(lhs_srcloc.cmp(rhs_srcloc));
return res;
auto lhs_expression = TRY(expression());
auto rhs_expression = TRY(rhs.expression());
@ -173,6 +193,14 @@ Result<Value> Syntax::copy_value() const {
return Value(Syntax(TRY(_value.copy())));
}
Result<Syntax> Syntax::copy() const { return Syntax(TRY(_value.copy())); }
Result<Value> SrcLoc::copy_value() const {
return Value(SrcLoc(TRY(_value.copy())));
}
Result<SrcLoc> SrcLoc::copy() const { return SrcLoc(TRY(_value.copy())); }
Result<Value> Pair::copy_value() const {
return Value(Pair(TRY(_value.copy())));
}

View file

@ -22,6 +22,8 @@ class Float;
class Bool;
class String;
class Symbol;
class SrcLoc;
class Symbol;
class Syntax;
class Pair;
class Array;
@ -63,6 +65,9 @@ class Object {
virtual Result<short> cmp(const Symbol&) const {
return cmp_tag(tag(), Tag::Symbol);
}
virtual Result<short> cmp(const SrcLoc&) const {
return cmp_tag(tag(), Tag::SrcLoc);
}
virtual Result<short> cmp(const Syntax&) const {
return cmp_tag(tag(), Tag::Syntax);
}
@ -636,12 +641,40 @@ class Symbol : public Object {
GcRoot<PodSymbol> _value;
};
class SrcLoc : public Object {
public:
SrcLoc() {}
SrcLoc(SrcLoc&& rhs) : _value(std::move(rhs._value)) {}
SrcLoc(GcRoot<PodSrcLoc>&& val) : _value(std::move(val)) {}
static Result<SrcLoc> create(const SourceRange& sourcerange);
virtual Tag tag() const final { return Tag::SrcLoc; }
virtual PodObject* pod() const final { return _value.get(); }
virtual Result<short> cmp(const Object& rhs) const final {
return -TRY(rhs.cmp(*this));
}
virtual Result<short> cmp(const SrcLoc& rhs) const final;
virtual void move(Object* obj) final { new (obj) SrcLoc(std::move(_value)); }
static Result<SrcLoc> create(PodSrcLoc* obj) {
return SrcLoc(TRY(MkGcRoot(obj)));
}
SourceRange sourcerange() const;
virtual Result<Value> copy_value() const final;
Result<SrcLoc> copy() const;
private:
GcRoot<PodSrcLoc> _value;
};
class Syntax : public Object {
public:
Syntax() {}
Syntax(Syntax&& rhs) : _value(std::move(rhs._value)) {}
Syntax(GcRoot<PodSyntax>&& val) : _value(std::move(val)) {}
static Result<Syntax> create(String filename, SourceRange sourcerange,
static Result<Syntax> create(String filename, SrcLoc srcloc,
Value expression);
virtual Tag tag() const final { return Tag::Syntax; }
virtual PodObject* pod() const final { return _value.get(); }
@ -657,7 +690,7 @@ class Syntax : public Object {
}
Result<Value> filename() const;
SourceRange sourcerange() const;
Result<Value> srcloc() const;
Result<Value> expression() const;
virtual Result<Value> copy_value() const final;

View file

@ -227,6 +227,7 @@ Result<Expression> Compiler::compile_expr(Context& context, const Value& expr) {
return compile_constant(context, expr);
case Tag::Float:
return compile_constant(context, expr);
case Tag::SrcLoc:
case Tag::Syntax:
case Tag::Array:
case Tag::ByteArray:

View file

@ -13,6 +13,7 @@ enum class Tag : uint8_t {
Bool,
String,
Symbol,
SrcLoc,
Syntax,
Pair,
Array,
@ -132,11 +133,17 @@ class PodSymbol final : public PodObject {
char32_t data[];
};
class PodSrcLoc : public PodObject {
public:
PodSrcLoc() : PodObject(Tag::SrcLoc) {};
SourceRange sourcerange;
};
class PodSyntax : public PodObject {
public:
PodSyntax() : PodObject(Tag::Syntax) {};
OffPtr<PodObject> filename;
SourceRange sourcerange;
OffPtr<PodObject> srcloc;
OffPtr<PodObject> expression;
};

View file

@ -2,6 +2,7 @@
#include "common.hpp"
#include "pod.hpp"
#include "sourcerange.hpp"
#include "writer.hpp"
typedef Result<Value> (*StdlibFunctionIdPtr)(const Array& params);
@ -86,6 +87,42 @@ Result<Value> stdlib_get(const Array& params) {
return TRY(collection.get(key));
}
Result<Value> stdlib_srcloc(const Array& params) {
Array array_copy = TRY(params.copy());
if (params.size() != 6) return ERROR(ArgumentCountMismatch);
SourceRange sr;
for (uint64_t i = 0; i < 6; i++) {
auto val = TRY(array_copy.get(i));
if (!val.is<Int64>()) return ERROR(TypeMismatch);
int64_t intval = val.to<Int64>()->value();
switch (i) {
case 0:
sr.start.line = intval;
break;
case 1:
sr.start.column = intval;
break;
case 2:
sr.start.offset = intval;
break;
case 3:
sr.end.line = intval;
break;
case 4:
sr.end.column = intval;
break;
case 5:
sr.end.offset = intval;
break;
default:
break;
}
}
return Value(TRY(SrcLoc::create(sr)));
}
#define STDLIB_FUNCTION(name, id) \
[(uint64_t)StdlibFunctionId::id] = {#name, StdlibFunctionId::id, \
stdlib_##name}
@ -100,6 +137,7 @@ static StdlibFunctionEntry function_entries[] = {
STDLIB_FUNCTION(list, List),
STDLIB_FUNCTION(array, Array),
STDLIB_FUNCTION(get, Get),
STDLIB_FUNCTION(srcloc, SrcLoc),
[(uint64_t)StdlibFunctionId::Max] = {0, StdlibFunctionId::Max,
stdlib_unknown},
};

View file

@ -14,6 +14,7 @@ enum class StdlibFunctionId : uint64_t {
List,
Array,
Get,
SrcLoc,
Max,
};

View file

@ -40,7 +40,7 @@ Result<void> run_repl() {
globals = TRY(vm.globals());
if (!res.is<Nil>()) {
debug_print(res);
TRY(debug_print(res));
}
}

View file

@ -2,6 +2,7 @@
#include "error.hpp"
#include "opcode.hpp"
#include "sourcerange.hpp"
Result<String> Writer::write_one(const Value& obj) {
switch (obj.tag()) {
@ -23,6 +24,8 @@ Result<String> Writer::write_one(const Value& obj) {
return write_string(*obj.to<String>());
case Tag::Symbol:
return write_symbol(*obj.to<Symbol>());
case Tag::SrcLoc:
return write_srcloc(*obj.to<SrcLoc>());
case Tag::Syntax:
return write_syntax(*obj.to<Syntax>());
case Tag::Pair:
@ -179,6 +182,19 @@ Result<String> Writer::write_symbol(const Symbol& val) {
return res;
}
Result<String> Writer::write_srcloc(const SrcLoc& val) {
char buf[1024];
String res = TRY(String::create("#<srcloc "));
SourceRange sr = val.sourcerange();
snprintf(buf, 1024, "%lu:%lu %lu:%lu", sr.start.line, sr.start.column,
sr.end.line, sr.end.column);
res = TRY(res.concat(buf));
res = TRY(res.concat(">"));
return res;
}
Result<String> Writer::write_syntax(const Syntax& val) {
return ERROR(NotImplemented);
}

View file

@ -21,6 +21,7 @@ class Writer {
Result<String> write_bytearray(const ByteArray& val);
Result<String> write_dict(const Dict& val);
Result<String> write_symbol(const Symbol& val);
Result<String> write_srcloc(const SrcLoc& val);
Result<String> write_syntax(const Syntax& val);
Result<String> write_opcode(const Opcode& val);
Result<String> write_function(const Function& val);