Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 21 additions & 23 deletions src/wasm/wat-lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ std::optional<int> getHexDigit(char c) {
// The result of lexing an integer token fragment.
struct LexIntResult : LexResult {
uint64_t n;
Signedness signedness;
Sign sign;
};

// Lexing context that accumulates lexed input to produce an integer token
Expand All @@ -133,8 +133,7 @@ struct LexIntCtx : LexCtx {

private:
uint64_t n = 0;
Signedness signedness = Unsigned;
bool negative = false;
Sign sign = NoSign;
bool overflow = false;

public:
Expand All @@ -143,42 +142,41 @@ struct LexIntCtx : LexCtx {
// Lex only the underlying span, ignoring the overflow and value.
std::optional<LexIntResult> lexedRaw() {
if (auto basic = LexCtx::lexed()) {
return LexIntResult{*basic, 0, Unsigned};
return LexIntResult{*basic, 0, NoSign};
}
return {};
}

std::optional<LexIntResult> lexed() {
// Check most significant bit for overflow of signed numbers.
if (overflow) {
return {};
}
auto basic = LexCtx::lexed();
if (!basic) {
return {};
}
if (signedness == Signed) {
if (negative) {
if (n > (1ull << 63)) {
// TODO: Add error production for signed underflow.
return {};
}
} else {
if (n > (1ull << 63) - 1) {
// TODO: Add error production for signed overflow.
return {};
}
// Check most significant bit for overflow of signed numbers.
if (sign == Neg) {
if (n > (1ull << 63)) {
// TODO: Add error production for signed underflow.
return {};
}
} else if (sign == Pos) {
if (n > (1ull << 63) - 1) {
// TODO: Add error production for signed overflow.
return {};
}
}
return LexIntResult{*basic, negative ? -n : n, signedness};
return LexIntResult{*basic, sign == Neg ? -n : n, sign};
}

void takeSign() {
if (takePrefix("+"sv)) {
signedness = Signed;
sign = Pos;
} else if (takePrefix("-"sv)) {
signedness = Signed;
negative = true;
sign = Neg;
} else {
sign = NoSign;
}
}

Expand Down Expand Up @@ -799,7 +797,7 @@ void Lexer::lexToken() {
} else if (auto t = ident(next())) {
tok = Token{t->span, IdTok{}};
} else if (auto t = integer(next())) {
tok = Token{t->span, IntTok{t->n, t->signedness}};
tok = Token{t->span, IntTok{t->n, t->sign}};
} else if (auto t = float_(next())) {
tok = Token{t->span, FloatTok{t->nanPayload, t->d}};
} else if (auto t = str(next())) {
Expand Down Expand Up @@ -834,7 +832,7 @@ bool TextPos::operator==(const TextPos& other) const {
}

bool IntTok::operator==(const IntTok& other) const {
return n == other.n && signedness == other.signedness;
return n == other.n && sign == other.sign;
}

bool FloatTok::operator==(const FloatTok& other) const {
Expand Down Expand Up @@ -872,7 +870,7 @@ std::ostream& operator<<(std::ostream& os, const RParenTok&) {
std::ostream& operator<<(std::ostream& os, const IdTok&) { return os << "id"; }

std::ostream& operator<<(std::ostream& os, const IntTok& tok) {
return os << tok.n << (tok.signedness == Signed ? " signed" : " unsigned");
return os << (tok.sign == Pos ? "+" : tok.sign == Neg ? "-" : "") << tok.n;
}

std::ostream& operator<<(std::ostream& os, const FloatTok& tok) {
Expand Down
4 changes: 2 additions & 2 deletions src/wat-lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ struct IdTok {
friend std::ostream& operator<<(std::ostream&, const IdTok&);
};

enum Signedness { Unsigned, Signed };
enum Sign { NoSign, Pos, Neg };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason we need to have both NoSign and Pos? Can't we make the default Pos, and change it to Neg only when we take -?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm nevermind. We need to distinguish u32 vs. s32...


struct IntTok {
uint64_t n;
Signedness signedness;
Sign sign;

bool operator==(const IntTok&) const;
friend std::ostream& operator<<(std::ostream&, const IntTok&);
Expand Down
Loading