Remove skipchar, add stdinlineno / stdincolno
With the new check function, this helper method doesn't make much sense to put in the standard library. To replicate the same result, we do need to expose the current line number; adding column number is a nice bonus. Also; made it a bit clearer when a check failes in it2. Also; the builtincheckfalse was not working. Also; separated out the test input file to have more data.
This commit is contained in:
parent
ed09d37213
commit
2eaa763a2c
@ -39,11 +39,6 @@ def skip():
|
|||||||
|
|
||||||
PEEK = None
|
PEEK = None
|
||||||
|
|
||||||
def skipchar(char):
|
|
||||||
global LINE
|
|
||||||
assert char == peek(), (LINE, char, peek())
|
|
||||||
skip()
|
|
||||||
|
|
||||||
def emitln(data):
|
def emitln(data):
|
||||||
emit(data)
|
emit(data)
|
||||||
emit(eol)
|
emit(eol)
|
||||||
@ -61,6 +56,11 @@ def lexident():
|
|||||||
|
|
||||||
return word
|
return word
|
||||||
|
|
||||||
|
def skipchar(char):
|
||||||
|
global LINE
|
||||||
|
assert char == peek(), (LINE, char, peek())
|
||||||
|
skip()
|
||||||
|
|
||||||
def parseconststring():
|
def parseconststring():
|
||||||
skipchar(quote)
|
skipchar(quote)
|
||||||
emit(quote)
|
emit(quote)
|
||||||
@ -364,33 +364,40 @@ def emitheader():
|
|||||||
emitln("eof = chr(0)")
|
emitln("eof = chr(0)")
|
||||||
emitln("eol = chr(10)")
|
emitln("eol = chr(10)")
|
||||||
emitln("quote = chr(34)")
|
emitln("quote = chr(34)")
|
||||||
emitln("PEEK = None")
|
emitln("")
|
||||||
emitln("LINE = 1")
|
emitln("STDINCOLNO = 0")
|
||||||
|
emitln("STDINLINENO = 1")
|
||||||
|
emitln("STDINPEEK = None")
|
||||||
|
emitln("")
|
||||||
|
emitln("def _readchar():")
|
||||||
|
emitln(" char = sys.stdin.read(1)")
|
||||||
|
emitln(" trace('char', char)")
|
||||||
|
emitln(" if not char:")
|
||||||
|
emitln(" return eof")
|
||||||
|
emitln(" return char")
|
||||||
emitln("")
|
emitln("")
|
||||||
emitln("def peek():")
|
emitln("def peek():")
|
||||||
emitln(" global PEEK")
|
emitln(" return STDINPEEK")
|
||||||
emitln(" if PEEK is None:")
|
|
||||||
emitln(" char = sys.stdin.read(1)")
|
|
||||||
emitln(" trace('char', char)")
|
|
||||||
emitln(" if not char:")
|
|
||||||
emitln(" PEEK = eof")
|
|
||||||
emitln(" else:")
|
|
||||||
emitln(" PEEK = char")
|
|
||||||
emitln(" return PEEK")
|
|
||||||
emitln("")
|
|
||||||
emitln("peek()")
|
|
||||||
emitln("")
|
emitln("")
|
||||||
emitln("def skip():")
|
emitln("def skip():")
|
||||||
emitln(" global LINE")
|
emitln(" global STDINCOLNO")
|
||||||
emitln(" global PEEK")
|
emitln(" global STDINLINENO")
|
||||||
emitln(" if eol == PEEK:")
|
emitln(" global STDINPEEK")
|
||||||
emitln(" LINE += 1")
|
emitln(" if eol == STDINPEEK:")
|
||||||
emitln(" PEEK = None")
|
emitln(" STDINLINENO += 1")
|
||||||
|
emitln(" STDINCOLNO = 0")
|
||||||
|
emitln(" STDINCOLNO += 1")
|
||||||
|
emitln(" STDINPEEK = _readchar()")
|
||||||
emitln("")
|
emitln("")
|
||||||
emitln("def skipchar(char):")
|
emitln("def stdinlineno():")
|
||||||
emitln(" global LINE")
|
emitln(" global STDINLINENO")
|
||||||
emitln(" assert char == peek(), (LINE, char, peek())")
|
emitln(" return str(STDINLINENO)")
|
||||||
emitln(" skip()")
|
emitln("")
|
||||||
|
emitln("def stdincolno():")
|
||||||
|
emitln(" global STDINCOLNO")
|
||||||
|
emitln(" return str(STDINCOLNO)")
|
||||||
|
emitln("")
|
||||||
|
emitln("skip()")
|
||||||
emitln("")
|
emitln("")
|
||||||
|
|
||||||
def emitfooter():
|
def emitfooter():
|
||||||
|
|||||||
@ -1,3 +1,14 @@
|
|||||||
|
skipchar exp:
|
||||||
|
declare act
|
||||||
|
declare lineno
|
||||||
|
declare colno
|
||||||
|
calc act peek
|
||||||
|
calc lineno stdinlineno
|
||||||
|
calc colno stdincolno
|
||||||
|
check eq exp act : "Unexpected character" act "expected" exp "at" lineno colno
|
||||||
|
skip
|
||||||
|
/
|
||||||
|
|
||||||
emitln data:
|
emitln data:
|
||||||
emit data
|
emit data
|
||||||
emit eol
|
emit eol
|
||||||
@ -430,33 +441,40 @@ emitheader:
|
|||||||
emitln "eof = chr(0)"
|
emitln "eof = chr(0)"
|
||||||
emitln "eol = chr(10)"
|
emitln "eol = chr(10)"
|
||||||
emitln "quote = chr(34)"
|
emitln "quote = chr(34)"
|
||||||
emitln "PEEK = None"
|
emitln ""
|
||||||
emitln "LINE = 1"
|
emitln "STDINCOLNO = 0"
|
||||||
|
emitln "STDINLINENO = 1"
|
||||||
|
emitln "STDINPEEK = None"
|
||||||
|
emitln ""
|
||||||
|
emitln "def _readchar():"
|
||||||
|
emitln " char = sys.stdin.read(1)"
|
||||||
|
emitln " trace('char', char)"
|
||||||
|
emitln " if not char:"
|
||||||
|
emitln " return eof"
|
||||||
|
emitln " return char"
|
||||||
emitln ""
|
emitln ""
|
||||||
emitln "def peek():"
|
emitln "def peek():"
|
||||||
emitln " global PEEK"
|
emitln " return STDINPEEK"
|
||||||
emitln " if PEEK is None:"
|
|
||||||
emitln " char = sys.stdin.read(1)"
|
|
||||||
emitln " trace('char', char)"
|
|
||||||
emitln " if not char:"
|
|
||||||
emitln " PEEK = eof"
|
|
||||||
emitln " else:"
|
|
||||||
emitln " PEEK = char"
|
|
||||||
emitln " return PEEK"
|
|
||||||
emitln ""
|
|
||||||
emitln "peek()"
|
|
||||||
emitln ""
|
emitln ""
|
||||||
emitln "def skip():"
|
emitln "def skip():"
|
||||||
emitln " global LINE"
|
emitln " global STDINCOLNO"
|
||||||
emitln " global PEEK"
|
emitln " global STDINLINENO"
|
||||||
emitln " if eol == PEEK:"
|
emitln " global STDINPEEK"
|
||||||
emitln " LINE += 1"
|
emitln " if eol == STDINPEEK:"
|
||||||
emitln " PEEK = None"
|
emitln " STDINLINENO += 1"
|
||||||
|
emitln " STDINCOLNO = 0"
|
||||||
|
emitln " STDINCOLNO += 1"
|
||||||
|
emitln " STDINPEEK = _readchar()"
|
||||||
emitln ""
|
emitln ""
|
||||||
emitln "def skipchar(char):"
|
emitln "def stdinlineno():"
|
||||||
emitln " global LINE"
|
emitln " global STDINLINENO"
|
||||||
emitln " assert char == peek(), (LINE, char, peek())"
|
emitln " return str(STDINLINENO)"
|
||||||
emitln " skip()"
|
emitln ""
|
||||||
|
emitln "def stdincolno():"
|
||||||
|
emitln " global STDINCOLNO"
|
||||||
|
emitln " return str(STDINCOLNO)"
|
||||||
|
emitln ""
|
||||||
|
emitln "skip()"
|
||||||
emitln ""
|
emitln ""
|
||||||
/
|
/
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,14 @@
|
|||||||
|
skipchar exp:
|
||||||
|
declare act
|
||||||
|
declare lineno
|
||||||
|
declare colno
|
||||||
|
calc act peek
|
||||||
|
calc lineno stdinlineno
|
||||||
|
calc colno stdincolno
|
||||||
|
check eq exp act : "Unexpected character" act "expected" exp "at" lineno colno
|
||||||
|
skip
|
||||||
|
/
|
||||||
|
|
||||||
emitln data:
|
emitln data:
|
||||||
emit data
|
emit data
|
||||||
emit eol
|
emit eol
|
||||||
@ -273,13 +284,23 @@ parsestatcheck indent:
|
|||||||
emit indent
|
emit indent
|
||||||
emitln "{"
|
emitln "{"
|
||||||
|
|
||||||
|
emit " fprintf(stderr, "
|
||||||
|
emit quote
|
||||||
|
emit "%s"
|
||||||
|
emit quote
|
||||||
|
emit ", "
|
||||||
|
emit quote
|
||||||
|
emit "ERROR:"
|
||||||
|
emit quote
|
||||||
|
emitln ");"
|
||||||
|
|
||||||
forever
|
forever
|
||||||
skipchar " "
|
skipchar " "
|
||||||
|
|
||||||
emit indent
|
emit indent
|
||||||
emit " fprintf(stderr, "
|
emit " fprintf(stderr, "
|
||||||
emit quote
|
emit quote
|
||||||
emit "%s "
|
emit " %s"
|
||||||
emit quote
|
emit quote
|
||||||
emit ", "
|
emit ", "
|
||||||
calc char peek
|
calc char peek
|
||||||
@ -568,35 +589,55 @@ emitheader:
|
|||||||
emitln " return 0;"
|
emitln " return 0;"
|
||||||
emitln "}"
|
emitln "}"
|
||||||
emitln ""
|
emitln ""
|
||||||
emitln "int LINE = 1;"
|
emitln "int STDINCOLNO = 1;"
|
||||||
|
emitln "int STDINLINENO = 1;"
|
||||||
|
emitln "char * STDINPEEK = 0;"
|
||||||
emitln ""
|
emitln ""
|
||||||
emitln "char * peek()"
|
emitln "char * _readchar()"
|
||||||
emitln "{"
|
emitln "{"
|
||||||
emitln " char * res = malloc(2*sizeof(char));"
|
emitln " char * res = malloc(2*sizeof(char));"
|
||||||
emitln " res[0] = getc(stdin);"
|
emitln " res[0] = getc(stdin);"
|
||||||
emitln " res[1] = 0;"
|
emitln " res[1] = 0;"
|
||||||
emitln " ungetc(res[0], stdin);"
|
|
||||||
emitln " return res;"
|
emitln " return res;"
|
||||||
emitln "}"
|
emitln "}"
|
||||||
emitln ""
|
emitln ""
|
||||||
|
emitln "char * peek()"
|
||||||
|
emitln "{"
|
||||||
|
emitln " if( !STDINPEEK ) STDINPEEK = _readchar(); // First byte read"
|
||||||
|
emitln " return STDINPEEK;"
|
||||||
|
emitln "}"
|
||||||
|
emitln ""
|
||||||
emitln "void skip()"
|
emitln "void skip()"
|
||||||
emitln "{"
|
emitln "{"
|
||||||
emitln " char c = getc(stdin);"
|
emitln " if( !STDINPEEK ) STDINPEEK = _readchar(); // First byte read, not even peek()'d"
|
||||||
emitln " if( c == 10 ) LINE += 1;"
|
emitln " if( STDINPEEK[0] == 10 ) {"
|
||||||
|
emitln " STDINLINENO += 1;"
|
||||||
|
emitln " STDINCOLNO = 0;"
|
||||||
|
emitln " }"
|
||||||
|
emitln " STDINCOLNO += 1;"
|
||||||
|
emitln " STDINPEEK = _readchar();"
|
||||||
emitln "}"
|
emitln "}"
|
||||||
emitln ""
|
emitln ""
|
||||||
emitln "void skipchar(char * chr)"
|
emitln "char * stdinlineno()"
|
||||||
emitln "{"
|
emitln "{"
|
||||||
emitln " assert(strlen(chr) == 1);"
|
emitln " char * res = malloc(8*sizeof(char));"
|
||||||
emitln " char * act = peek();"
|
emit " sprintf(res, "
|
||||||
emitln " assert(strlen(act) == 1);"
|
|
||||||
emitln " if( chr[0] == act[0] ) {skip(); return;};"
|
|
||||||
emit " fprintf(stderr, "
|
|
||||||
emit quote
|
emit quote
|
||||||
emit "Expected '%c' on line %d but saw '%c' instead%c"
|
emit "%d"
|
||||||
emit quote
|
emit quote
|
||||||
emitln ", chr[0], LINE, act[0], 10);"
|
emitln ", STDINLINENO);"
|
||||||
emitln " exit(1);"
|
emitln " return res;"
|
||||||
|
emitln "}"
|
||||||
|
emitln ""
|
||||||
|
emitln "char * stdincolno()"
|
||||||
|
emitln "{"
|
||||||
|
emitln " char * res = malloc(8*sizeof(char));"
|
||||||
|
emit " sprintf(res, "
|
||||||
|
emit quote
|
||||||
|
emit "%d"
|
||||||
|
emit quote
|
||||||
|
emitln ", STDINCOLNO);"
|
||||||
|
emitln " return res;"
|
||||||
emitln "}"
|
emitln "}"
|
||||||
emitln ""
|
emitln ""
|
||||||
return
|
return
|
||||||
|
|||||||
@ -151,9 +151,13 @@ Checks stdin for the next character and returns it.
|
|||||||
|
|
||||||
Advances stdin a single character.
|
Advances stdin a single character.
|
||||||
|
|
||||||
#### skipchar a
|
#### stdincolno
|
||||||
|
|
||||||
Advances stdin a single character, if it matches the first character of `a`. Otherwise, exits the program.
|
Returns the column number for stdin (starting at 1)
|
||||||
|
|
||||||
|
#### stdinlineno
|
||||||
|
|
||||||
|
Returns the line number for stdin (starting at 1)
|
||||||
|
|
||||||
### Typing
|
### Typing
|
||||||
|
|
||||||
|
|||||||
@ -18,18 +18,18 @@ check: all-it0.results all-it1.results all-it2.results
|
|||||||
|
|
||||||
all-it0.results: $(addprefix build/,$(addsuffix .it0, $(TESTLIST))) build/builtincheckfalse.it0
|
all-it0.results: $(addprefix build/,$(addsuffix .it0, $(TESTLIST))) build/builtincheckfalse.it0
|
||||||
-rm -f $@
|
-rm -f $@
|
||||||
echo "Hello" | build/builtincheckfalse.it0 2> /dev/null 2>&1 | grep 'Success'
|
cat test-input.txt | build/builtincheckfalse.it0 2> /dev/null 2>&1 | grep 'Success'
|
||||||
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; echo "Hello" | ./build/$(test).it0 >> $@ ; echo "" >> $@ ;)
|
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; cat test-input.txt | ./build/$(test).it0 >> $@ ; echo "" >> $@ ;)
|
||||||
|
|
||||||
all-it1.results: $(addprefix build/,$(addsuffix .it1, $(TESTLIST))) build/builtincheckfalse.it0
|
all-it1.results: $(addprefix build/,$(addsuffix .it1, $(TESTLIST))) build/builtincheckfalse.it1
|
||||||
-rm -f $@
|
-rm -f $@
|
||||||
echo "Hello" | build/builtincheckfalse.it0 2> /dev/null 2>&1 | grep 'Success'
|
cat test-input.txt | build/builtincheckfalse.it1 2> /dev/null 2>&1 | grep 'Success'
|
||||||
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; echo "Hello" | ./build/$(test).it1 >> $@ ; echo "" >> $@ ;)
|
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; cat test-input.txt | ./build/$(test).it1 >> $@ ; echo "" >> $@ ;)
|
||||||
|
|
||||||
all-it2.results: $(addprefix build/,$(addsuffix .it2, $(TESTLIST))) build/builtincheckfalse.it0
|
all-it2.results: $(addprefix build/,$(addsuffix .it2, $(TESTLIST))) build/builtincheckfalse.it2
|
||||||
-rm -f $@
|
-rm -f $@
|
||||||
echo "Hello" | build/builtincheckfalse.it0 2> /dev/null 2>&1 | grep 'Success'
|
cat test-input.txt | build/builtincheckfalse.it2 2> /dev/null 2>&1 | grep 'Success'
|
||||||
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; echo "Hello" | ./build/$(test).it2 >> $@ ; echo "" >> $@ ;)
|
$(foreach test,$(TESTLIST), echo -n "$(test) " >> $@; cat test-input.txt | ./build/$(test).it2 >> $@ ; echo "" >> $@ ;)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -f *.results build/*.it0* build/*.it1* build/*.it2*
|
-rm -f *.results build/*.it0* build/*.it1* build/*.it2*
|
||||||
|
|||||||
86
tests/stdinlineno.lang0
Normal file
86
tests/stdinlineno.lang0
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
main:
|
||||||
|
declare char
|
||||||
|
declare colno
|
||||||
|
declare lineno
|
||||||
|
|
||||||
|
calc char peek
|
||||||
|
calc colno stdincolno
|
||||||
|
calc lineno stdinlineno
|
||||||
|
check eq char "H" : "Read: H" char
|
||||||
|
check eq colno "1" : "The column number should not have advanced yet" colno
|
||||||
|
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||||
|
skip
|
||||||
|
|
||||||
|
calc char peek
|
||||||
|
calc colno stdincolno
|
||||||
|
calc lineno stdinlineno
|
||||||
|
check eq char "e" : "Read: e" char
|
||||||
|
check eq colno "2" : "The column number should have been advanced by 1" colno
|
||||||
|
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||||
|
skip
|
||||||
|
|
||||||
|
calc char peek
|
||||||
|
calc colno stdincolno
|
||||||
|
calc lineno stdinlineno
|
||||||
|
check eq char "l" : "Read: l" char
|
||||||
|
check eq colno "3" : "The column number should have been advanced by 2" colno
|
||||||
|
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||||
|
skip
|
||||||
|
|
||||||
|
calc char peek
|
||||||
|
calc colno stdincolno
|
||||||
|
calc lineno stdinlineno
|
||||||
|
check eq char "l" : "Read: l" char
|
||||||
|
check eq colno "4" : "The column number should have been advanced by 3" colno
|
||||||
|
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||||
|
skip
|
||||||
|
|
||||||
|
calc char peek
|
||||||
|
calc colno stdincolno
|
||||||
|
calc lineno stdinlineno
|
||||||
|
check eq char "o" : "Read: o" char
|
||||||
|
check eq colno "5" : "The column number should have been advanced by 4" colno
|
||||||
|
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||||
|
skip
|
||||||
|
|
||||||
|
calc char peek
|
||||||
|
calc colno stdincolno
|
||||||
|
calc lineno stdinlineno
|
||||||
|
check eq char "!" : "Read: !" char
|
||||||
|
check eq colno "6" : "The column number should have been advanced by 5" colno
|
||||||
|
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||||
|
skip
|
||||||
|
|
||||||
|
calc char peek
|
||||||
|
calc colno stdincolno
|
||||||
|
calc lineno stdinlineno
|
||||||
|
check eq char eol : "Read: eol" char
|
||||||
|
check eq colno "7" : "The column number should have been advanced by 6" colno
|
||||||
|
check eq lineno "1" : "The line number should not have advanced yet" lineno
|
||||||
|
skip
|
||||||
|
|
||||||
|
calc char peek
|
||||||
|
calc colno stdincolno
|
||||||
|
calc lineno stdinlineno
|
||||||
|
check eq char eol : "Read: eol" char
|
||||||
|
check eq colno "1" : "The column number should have been reset" colno
|
||||||
|
check eq lineno "2" : "The line number should have advanced by 1" lineno
|
||||||
|
skip
|
||||||
|
|
||||||
|
calc char peek
|
||||||
|
calc colno stdincolno
|
||||||
|
calc lineno stdinlineno
|
||||||
|
check eq char "T" : "Read: T" char
|
||||||
|
check eq colno "1" : "The column number should have been reset again" colno
|
||||||
|
check eq lineno "3" : "The line number should have advanced by 2" lineno
|
||||||
|
skip
|
||||||
|
|
||||||
|
calc char peek
|
||||||
|
calc colno stdincolno
|
||||||
|
calc lineno stdinlineno
|
||||||
|
check eq char "h" : "Read: h" char
|
||||||
|
check eq colno "2" : "The line number should not have been advanced by 1" colno
|
||||||
|
check eq lineno "3" : "The line number should not have advanced further" lineno
|
||||||
|
|
||||||
|
emit "Success"
|
||||||
|
/
|
||||||
3
tests/test-input.txt
Normal file
3
tests/test-input.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Hello!
|
||||||
|
|
||||||
|
This is an example of standard input.
|
||||||
Loading…
x
Reference in New Issue
Block a user