-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added buffer in get_ch() for line continuation lookahead #136
Changes from 1 commit
e5699fa
97d8b2f
7c2343a
23b6ec2
391e186
8421f15
445aa0a
b7d57f4
c4656ee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,8 @@ | |
// Use positional parameter directly for function parameters that are constants | ||
#define OPTIMIZE_CONSTANT_PARAM_not | ||
#define SUPPORT_ADDRESS_OF_OP_not | ||
// Make get_ch() use a length-1 character buffer to lookahead and skip line continuations | ||
#define SUPPORT_LINE_CONTINUATION | ||
|
||
// Shell backend codegen options | ||
#ifndef SH_AVOID_PRINTF_USE_NOT | ||
|
@@ -242,7 +244,11 @@ void syntax_error(char *msg) { | |
|
||
// tokenizer | ||
|
||
#define CHBUF_SIZE 1 | ||
int ch; | ||
int chbuf[CHBUF_SIZE]; | ||
int chbuf_head = -1; | ||
int chbuf_tail = 0; | ||
#ifdef DEBUG_EXPAND_INCLUDES | ||
int prev_ch = EOF; | ||
#endif | ||
|
@@ -607,7 +613,30 @@ void output_declaration_c_code(bool no_header) { | |
#endif | ||
|
||
void get_ch() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we could simplify the whole thing by separating
That way we wouldn't need to repeat the location logic. And when |
||
#ifdef SUPPORT_LINE_CONTINUATION | ||
if(chbuf_head > -1) { | ||
ch = chbuf[chbuf_head++]; | ||
if(chbuf_head == chbuf_tail) | ||
chbuf_head = -1; | ||
} else { | ||
laurenthuberdeau marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ch = fgetc(fp); | ||
|
||
if(ch == '\\') { | ||
ch = fgetc(fp); | ||
|
||
if(ch != '\n'){ // The character isn't a newline, so this is an escape sequence: | ||
chbuf[0] = ch; // Put the character back in the character buffer for future consumption | ||
chbuf_tail = 1; // Set the character buffer size | ||
chbuf_head = 0; // Set the pointer to the character buffer | ||
ch = '\\'; // Restore the character that was read on this call | ||
} else { // The character is a newline, so this is a line continuation which we want to bypass | ||
ch = fgetc(fp); // Consume yet another character, the next one for logical parsing | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'll want to increment the line and column number if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done - as a side note, I haven't looked extensively at the debug error messages, but it seems the debug output always says the error is one line up from where it actually is - but I'm guessing that's because the tokenizer is behind where the input is being consumed? Is that right/ expected? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The error location can be off by a few lines when the code generator throws the error. That's because we parse each declaration fully before passing it to the code generator, so the I've been thinking of annotating the AST objects with the values of When the error is thrown by the parser however, I haven't noticed the error location to be wrong. Do you have an example? |
||
} | ||
} | ||
} | ||
#else | ||
ch = fgetc(fp); | ||
#endif | ||
if (ch == EOF) { | ||
// If it's not the last file on the stack, EOF means that we need to switch to the next file | ||
if (include_stack->next != 0) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#include <stdio.h> | ||
|
||
#ifdef PNUT_CC | ||
|
||
typedef char *va_list; | ||
|
||
#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof last+3)&~3) | ||
#define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3))) | ||
#define va_end(ap) | ||
|
||
#else | ||
|
||
#include <stdarg.h> | ||
|
||
#endif | ||
|
||
void putint_aux(int n, int base) { | ||
int d = n % base; | ||
int top = n / base; | ||
if (n == 0) return; | ||
putint_aux(top, base); | ||
putchar("0123456789abcdef"[d & 15]); | ||
} | ||
|
||
void putint(int n, int base) { | ||
if (n < 0) { | ||
putchar('-'); | ||
putint_aux(-n, base); | ||
} else { | ||
putint_aux(n, base); | ||
} | ||
} | ||
|
||
void putstr(char *s) { | ||
while (*s) { | ||
putchar(*s); | ||
s++; | ||
} | ||
} | ||
|
||
// A simple version of printf that supports %d, %c, %x, %s | ||
void simple_printf(char *fmt, ...) { | ||
va_list ap; | ||
va_start(ap, fmt); | ||
while (*fmt) { | ||
if (*fmt == '%') { | ||
fmt++; | ||
switch (*fmt) { | ||
case 'd': | ||
putint(va_arg(ap, int), 10); | ||
break; | ||
case 'c': | ||
putchar(va_arg(ap, int)); | ||
break; | ||
case 'x': | ||
putint(va_arg(ap, int), 16); | ||
break; | ||
case 's': | ||
putstr(va_arg(ap, char *)); | ||
break; | ||
default: | ||
putchar(*fmt); | ||
break; | ||
} | ||
} else { | ||
putchar(*fmt); | ||
} | ||
fmt++; | ||
} | ||
va_end(ap); | ||
} | ||
|
||
void main() { | ||
|
||
/**/ | ||
int foo = 0; | ||
|
||
/\ | ||
* | ||
*/ fo\ | ||
o +\ | ||
= 0\ | ||
x\ | ||
10\ | ||
200; | ||
|
||
simple_printf("%d", foo); | ||
laurenthuberdeau marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
66048 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#include <stdio.h> | ||
|
||
void main() { | ||
|
||
/**/ | ||
int foo = 0; | ||
|
||
/\ | ||
* | ||
*/ fo\ | ||
o +\ | ||
= 0\ | ||
x\ | ||
10\ | ||
200; | ||
|
||
printf("%d", foo); | ||
laurenthuberdeau marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
66048 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how a buffer larger than 1 would be useful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure - I implemented it as the concept it was meant to be such that it was future proof if the tokenizer needed to do longer lookahead eventually, but it could be simplified down to just an integer variable and without the tail pointer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to keep it as simple as possible. We can always add the buffer and tail pointer back if we need it. Also, this should be in a
#ifdef SUPPORT_LINE_CONTINUATION
block.