Skip to content

Commit

Permalink
boostrap: remove preprocessor code
Browse files Browse the repository at this point in the history
  • Loading branch information
StunxFS committed Dec 25, 2023
1 parent c82c881 commit 41b10be
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 183 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ quality.
* **Not NULL values by default**: This is only possible with option types (`?T`) and `none`.
* **Easy error handling**: With result types, `func my_func() -> !T { ... }`,
`throw` and `catch`.
* **A basic preprocessor**: `if`, `else_if`, `else` and `endif` for optional code using
flags (`-D my_flag`).
* **Immutable values**: Variables and fields are immutable by default.
structs have internal immutability.
* **Polymorphism**: Traits, Embedded Structs and Tagged Enums are supported.
Expand Down Expand Up @@ -88,4 +86,4 @@ successfully.
Only linux is supported for now. Windows is not well supported, and macOS is not supported
yet. Any help to provide full support for both Windows and macOS is welcome.

Read [CONTRIBUTING](CONTRIBUTING.md) to get more information.
Read [CONTRIBUTING](CONTRIBUTING.md) to get more information.
181 changes: 1 addition & 180 deletions rivetc/src/lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,10 +601,7 @@ def internal_next(self):
return token.Token("", Kind.OrElse, pos)
return token.Token("", Kind.Question, pos)
elif ch == "#":
if nextc == "[" or nextc == "!":
return token.Token("", Kind.Hash, pos)
self.pp_directive()
continue
return token.Token("", Kind.Hash, pos)
elif ch == "&":
if nextc == "&" and self.look_ahead(2).isspace():
self.pos += 1
Expand Down Expand Up @@ -667,179 +664,3 @@ def internal_next(self):
report.error(f"invalid character `{ch}`", pos)
break
return token.Token("", Kind.EOF, self.current_pos())

def pp_directive(self):
pos = self.current_pos()
report.warn("deprecated", pos)
self.pos += 1 # skip '#'
self.skip_whitespace()
kw = self.read_ident()
self.skip_whitespace()
if kw == "if":
self.pp_if()
elif kw == "else_if":
self.pp_else_if()
elif kw == "else":
self.pp_else()
elif kw == "endif":
self.pp_endif()
elif kw in ("error", "warn"):
self.pp_err_warn(kw)
else:
report.error(f"invalid preprocessing directive: `{kw}`", pos)
return
if len(self.conditional_stack
) > 0 and self.conditional_stack[-1].skip_section:
# skip tokens until next preprocessing directive
while self.pos < self.text_len:
cc = self.current_char()
if cc == '#' and not (
self.matches("#error", self.pos)
or self.matches("#warn", self.pos)
):
self.pos -= 1
return
elif cc == '\n':
self.inc_line_number()
self.pos += 1
# if we get EOF, then no corresponding `#endif` has been written
if self.pos == self.text_len:
report.error("expected `#endif`, found end of file", pos)

def pp_if(self):
self.pos += 1
self.skip_whitespace()
cond = self.pp_expression()
self.skip_whitespace()
self.conditional_stack.append(Conditional())
if cond and (
len(self.conditional_stack) == 1
or not self.conditional_stack[-2].skip_section
):
# condition true => process code within if
self.conditional_stack[-1].matched = True
self.conditional_stack[-1].skip_section = False
else:
# skip lines until next preprocessing directive
self.conditional_stack[-1].skip_section = True
self.pos -= 1

def pp_else_if(self):
self.pos += 1
pos = self.current_pos()
self.skip_whitespace()
cond = self.pp_expression()
self.skip_whitespace()
if len(self.conditional_stack
) == 0 or self.conditional_stack[-1].else_found:
report.error("unexpected `#else_if`", pos)
elif cond and (not self.conditional_stack[-1].matched) and (
len(self.conditional_stack) == 1
or not self.conditional_stack[-2].skip_section
):
# condition true => process code within if
self.conditional_stack[-1].matched = True
self.conditional_stack[-1].skip_section = False
else:
# skip lines until next preprocessing directive
self.conditional_stack[-1].skip_section = True
self.pos -= 1

def pp_else(self):
pos = self.current_pos()
self.skip_whitespace()
if len(self.conditional_stack
) == 0 or self.conditional_stack[-1].else_found:
report.error("unexpected `#else`", pos)
elif (not self.conditional_stack[-1].matched) and (
len(self.conditional_stack) == 1
or not self.conditional_stack[-2].skip_section
):
# condition true => process code within if
self.conditional_stack[-1].matched = True
self.conditional_stack[-1].skip_section = False
else:
# skip lines until next preprocessing directive
self.conditional_stack[-1].skip_section = True

def pp_endif(self):
pos = self.current_pos()
if len(self.conditional_stack) == 0:
report.error("unexpected `#endif`", pos)
return
self.conditional_stack.pop()

def pp_err_warn(self, kind):
pos = self.current_pos()
self.pos += 1
start = self.pos
self.ignore_line()
msg = self.text[start:self.pos].strip()
if kind == "error":
report.error(f"#error: {msg}", pos)
else:
report.warn(f"#warn: {msg}", pos)

def pp_expression(self):
return self.pp_or_expression()

def pp_or_expression(self):
left = self.pp_and_expression()
self.skip_whitespace()
while self.pos < self.text_len and self.matches("||", self.pos):
self.pos += 2
self.skip_whitespace()
right = self.pp_and_expression()
left = left or right
return left

def pp_and_expression(self):
left = self.pp_unary_expression()
self.skip_whitespace()
while self.pos < self.text_len and self.matches("&&", self.pos):
self.pos += 2
self.skip_whitespace()
right = self.pp_unary_expression()
left = left and right
return left

def pp_unary_expression(self):
if self.pos < self.text_len and self.current_char() == "!":
self.pos += 1
self.skip_whitespace()
return not self.pp_unary_expression()
return self.pp_primary_expression()

def pp_primary_expression(self):
pos = self.current_pos()
cc = self.current_char()
if self.pos >= self.text_len:
report.error("expected name, found end of file", pos)
elif utils.is_valid_name(cc):
return self.pp_symbol()
elif cc == '(':
self.pos += 1
self.skip_whitespace()
result = self.pp_expression()
self.skip_whitespace()
cc = self.current_char()
if self.pos < self.text_len and cc == ')':
self.pos += 1
else:
report.error(f"expected `)`, found `{cc}`", self.current_pos())
return result
return False

def pp_symbol(self):
pos = self.current_pos()
p = self.current_char()
ident = self.read_ident()
self.pos += 1
defined = False
if ident == "true":
defined = True
elif ident == "false":
defined = False
else:
defined = self.comp.evalue_comptime_ident(ident, pos)
return defined

0 comments on commit 41b10be

Please sign in to comment.