diff --git a/src/arena.cpp b/src/arena.cpp index 2834774..9383a28 100644 --- a/src/arena.cpp +++ b/src/arena.cpp @@ -138,7 +138,15 @@ Result Arena::gc_symbol(PodSymbol* obj) { } Result Arena::gc_syntax(PodSyntax* obj) { - return ERROR(NotImplemented); + auto nobj = TRY(alloc()); + + nobj->header.tag = Tag::Syntax; + + nobj->filename = TRY(gc_pod(obj->filename.get())); + nobj->sourcerange = obj->sourcerange; + nobj->expression = TRY(gc_pod(obj->expression.get())); + + return nobj; } Result Arena::gc_pair(PodPair* obj) { diff --git a/src/common.cpp b/src/common.cpp index d67824c..75d0f4b 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -3,16 +3,11 @@ #include "arena.hpp" #include "error.hpp" #include "pod.hpp" +#include "sourcerange.hpp" #include "stdlib.hpp" #include "utf8.hpp" #include "writer.hpp" -Syntax::Syntax(String filename, String modulename, Value expression) {} - -Result Syntax::get_value() { - return Value::create(_value->expression.get()); -} - Result Value::create(PodObject* obj) { switch (obj->header.tag) { case Tag::Nil: @@ -82,11 +77,64 @@ Result ByteArray::create(const String& str) { return ByteArray(TRY(MkGcRoot(pod))); } +Result Syntax::create(String filename, SourceRange sourcerange, + Value expression) { + auto pod = TRY(arena_alloc()); + pod->header.tag = Tag::Syntax; + pod->filename = filename.pod(); + pod->sourcerange = sourcerange; + pod->expression = expression.pod(); + + return Syntax(TRY(MkGcRoot(pod))); +} + +short sourceposition_cmp(const SourcePosition& lhs, const SourcePosition& rhs) { + short res = (lhs.line > rhs.line) - (lhs.line < rhs.line); + if (res != 0) return res; + res = (lhs.column > rhs.column) - (lhs.column < rhs.column); + if (res != 0) return res; + return (lhs.offset > rhs.offset) - (lhs.offset < rhs.offset); +} + +short sourcerange_cmp(const SourceRange& lhs, const SourceRange rhs) { + short res = sourceposition_cmp(lhs.start, rhs.start); + if (res != 0) return res; + + return sourceposition_cmp(lhs.end, rhs.end); +} + +Result Syntax::filename() const { + return Value::create(_value->filename.get()); +} + +SourceRange Syntax::sourcerange() const { return _value->sourcerange; } + +Result Syntax::expression() const { + return Value::create(_value->expression.get()); +} + +Result Syntax::cmp(const Syntax& rhs) const { + auto lhs_filename = TRY(filename()); + auto rhs_filename = TRY(rhs.filename()); + 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_expression = TRY(expression()); + auto rhs_expression = TRY(rhs.expression()); + res = TRY(lhs_expression.cmp(rhs_expression)); + return res; +} + Result syntax_unwrap(Value& val) { Syntax* syntax = val.to(); if (syntax == 0) return val.copy(); - return syntax->get_value(); + return syntax->expression(); } Result Nil::copy_value() const { return Value(Nil(TRY(_value.copy()))); } diff --git a/src/common.hpp b/src/common.hpp index b2d7f96..99bb12a 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -641,13 +641,14 @@ class Syntax : public Object { Syntax() {} Syntax(Syntax&& rhs) : _value(std::move(rhs._value)) {} Syntax(GcRoot&& val) : _value(std::move(val)) {} - Syntax(String filename, String modulename, Value expression); + static Result create(String filename, SourceRange sourcerange, + Value expression); virtual Tag tag() const final { return Tag::Syntax; } virtual PodObject* pod() const final { return _value.get(); } virtual Result cmp(const Object& rhs) const final { return -TRY(rhs.cmp(*this)); } - virtual Result cmp(const Syntax& rhs) const final { return 0; } + virtual Result cmp(const Syntax& rhs) const final; virtual void move(Object* obj) final { new (obj) Syntax(std::move(_value)); } @@ -655,7 +656,9 @@ class Syntax : public Object { return Syntax(TRY(MkGcRoot(obj))); } - Result get_value(); + Result filename() const; + SourceRange sourcerange() const; + Result expression() const; virtual Result copy_value() const final; Result copy() const; diff --git a/src/pod.hpp b/src/pod.hpp index 3773a62..f618dec 100644 --- a/src/pod.hpp +++ b/src/pod.hpp @@ -135,10 +135,9 @@ class PodSymbol final : public PodObject { class PodSyntax : public PodObject { public: PodSyntax() : PodObject(Tag::Syntax) {}; - OffPtr filename; - OffPtr modulename; - OffPtr expression; + OffPtr filename; SourceRange sourcerange; + OffPtr expression; }; class PodPair : public PodObject {