mirror of
https://github.com/irmen/prog8.git
synced 2024-10-26 07:27:41 +00:00
character literals (strings of len 1) are no longer automatically converted to byte integers
This commit is contained in:
parent
890fcffdfa
commit
780443ddab
@ -58,6 +58,7 @@ class PlyParser:
|
|||||||
|
|
||||||
def lexer_error(self, sourceref: SourceRef, fmtstring: str, *args: str) -> None:
|
def lexer_error(self, sourceref: SourceRef, fmtstring: str, *args: str) -> None:
|
||||||
self.parse_errors += 1
|
self.parse_errors += 1
|
||||||
|
self.print_error_sourceline(sourceref)
|
||||||
print_bold("ERROR: {}: {}".format(sourceref, fmtstring.format(*args)))
|
print_bold("ERROR: {}: {}".format(sourceref, fmtstring.format(*args)))
|
||||||
|
|
||||||
def _check_last_statement_is_return(self, last_stmt: AstNode) -> None:
|
def _check_last_statement_is_return(self, last_stmt: AstNode) -> None:
|
||||||
@ -508,15 +509,20 @@ class PlyParser:
|
|||||||
print("Error (in imported file):", str(exc), file=out)
|
print("Error (in imported file):", str(exc), file=out)
|
||||||
else:
|
else:
|
||||||
print("Error:", str(exc), file=out)
|
print("Error:", str(exc), file=out)
|
||||||
sourcetext = linecache.getline(exc.sourceref.file, exc.sourceref.line).rstrip()
|
self.print_error_sourceline(exc.sourceref)
|
||||||
if sourcetext:
|
|
||||||
print(" " + sourcetext.expandtabs(8), file=out)
|
|
||||||
if exc.sourceref.column:
|
|
||||||
print(' ' * (1+exc.sourceref.column) + '^', file=out)
|
|
||||||
if out.isatty():
|
if out.isatty():
|
||||||
print("\x1b[0m", file=out, end="", flush=True)
|
print("\x1b[0m", file=out, end="", flush=True)
|
||||||
raise exc # XXX temporary to see where the error occurred
|
raise exc # XXX temporary to see where the error occurred
|
||||||
|
|
||||||
|
def print_error_sourceline(self, sref: SourceRef) -> None:
|
||||||
|
if not sref:
|
||||||
|
return
|
||||||
|
sourcetext = linecache.getline(sref.file, sref.line).rstrip()
|
||||||
|
if sourcetext:
|
||||||
|
print(" " + sourcetext.expandtabs(8))
|
||||||
|
if sref.column:
|
||||||
|
print(' ' * (1+sref.column) + '^')
|
||||||
|
|
||||||
|
|
||||||
class Zeropage:
|
class Zeropage:
|
||||||
SCRATCH_B1 = 0x02
|
SCRATCH_B1 = 0x02
|
||||||
|
@ -9,8 +9,8 @@ import os
|
|||||||
import datetime
|
import datetime
|
||||||
from typing import TextIO, Callable, no_type_check
|
from typing import TextIO, Callable, no_type_check
|
||||||
from ..plylex import print_bold
|
from ..plylex import print_bold
|
||||||
from ..plyparse import Module, Scope, ProgramFormat, Block, Directive, VarDef, Label, Subroutine, AstNode, ZpOptions, \
|
from ..plyparse import (Module, ProgramFormat, Block, Directive, VarDef, Label, Subroutine, ZpOptions,
|
||||||
InlineAssembly, Return, Register, Goto, SubCall, Assignment, AugAssignment, IncrDecr, AssignmentTargets
|
InlineAssembly, Return, Register, Goto, SubCall, Assignment, AugAssignment, IncrDecr, AssignmentTargets)
|
||||||
from . import CodeError, to_hex, to_mflpt5, Context
|
from . import CodeError, to_hex, to_mflpt5, Context
|
||||||
from .variables import generate_block_init, generate_block_vars
|
from .variables import generate_block_init, generate_block_vars
|
||||||
from .assignment import generate_assignment, generate_aug_assignment
|
from .assignment import generate_assignment, generate_aug_assignment
|
||||||
|
@ -7,8 +7,8 @@ Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
|||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import Dict, List, Callable, Any, no_type_check
|
from typing import Dict, List, Callable, Any, no_type_check
|
||||||
from ..plyparse import Block, VarType, VarDef, LiteralValue, AddressOf
|
from ..plyparse import Block, VarDef, LiteralValue, AddressOf
|
||||||
from ..datatypes import DataType, STRING_DATATYPES
|
from ..datatypes import DataType, VarType, STRING_DATATYPES
|
||||||
from . import to_hex, to_mflpt5, CodeError
|
from . import to_hex, to_mflpt5, CodeError
|
||||||
|
|
||||||
|
|
||||||
@ -173,12 +173,13 @@ def generate_block_vars(out: Callable, block: Block, zeropage: bool=False) -> No
|
|||||||
for vardef in vars_by_vartype.get(VarType.VAR, []):
|
for vardef in vars_by_vartype.get(VarType.VAR, []):
|
||||||
if vardef.datatype.isnumeric():
|
if vardef.datatype.isnumeric():
|
||||||
assert vardef.size == [1]
|
assert vardef.size == [1]
|
||||||
|
assert isinstance(vardef.value, LiteralValue)
|
||||||
if vardef.datatype == DataType.BYTE:
|
if vardef.datatype == DataType.BYTE:
|
||||||
out("{:s}\v.byte ?".format(vardef.name))
|
out("{:s}\v.byte ?\t; {:s}".format(vardef.name, to_hex(vardef.value.value)))
|
||||||
elif vardef.datatype == DataType.WORD:
|
elif vardef.datatype == DataType.WORD:
|
||||||
out("{:s}\v.word ?".format(vardef.name))
|
out("{:s}\v.word ?\t; {:s}".format(vardef.name, to_hex(vardef.value.value)))
|
||||||
elif vardef.datatype == DataType.FLOAT:
|
elif vardef.datatype == DataType.FLOAT:
|
||||||
out("{:s}\v.fill 5\t\t; float".format(vardef.name))
|
out("{:s}\v.fill 5\t\t; float {}".format(vardef.name, vardef.value.value))
|
||||||
else:
|
else:
|
||||||
raise CodeError("weird datatype")
|
raise CodeError("weird datatype")
|
||||||
elif vardef.datatype in (DataType.BYTEARRAY, DataType.WORDARRAY):
|
elif vardef.datatype in (DataType.BYTEARRAY, DataType.WORDARRAY):
|
||||||
|
@ -14,8 +14,8 @@ from typing import Union, Generator, Tuple, List, Optional, Dict, Any, no_type_c
|
|||||||
import attr
|
import attr
|
||||||
from ply.yacc import yacc
|
from ply.yacc import yacc
|
||||||
from .plylex import SourceRef, tokens, lexer, find_tok_column, print_warning
|
from .plylex import SourceRef, tokens, lexer, find_tok_column, print_warning
|
||||||
from .datatypes import DataType, VarType, REGISTER_SYMBOLS, REGISTER_BYTES, REGISTER_WORDS, \
|
from .datatypes import (DataType, VarType, REGISTER_SYMBOLS, REGISTER_BYTES, REGISTER_WORDS,
|
||||||
char_to_bytevalue, FLOAT_MAX_NEGATIVE, FLOAT_MAX_POSITIVE
|
FLOAT_MAX_NEGATIVE, FLOAT_MAX_POSITIVE, char_to_bytevalue)
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["ProgramFormat", "ZpOptions", "math_functions", "builtin_functions", "ParseError", "ExpressionEvaluationError",
|
__all__ = ["ProgramFormat", "ZpOptions", "math_functions", "builtin_functions", "ParseError", "ExpressionEvaluationError",
|
||||||
@ -1224,9 +1224,7 @@ def p_literal_value(p):
|
|||||||
| CHARACTER
|
| CHARACTER
|
||||||
| BOOLEAN"""
|
| BOOLEAN"""
|
||||||
tok = p.slice[-1]
|
tok = p.slice[-1]
|
||||||
if tok.type == "CHARACTER":
|
if tok.type == "BOOLEAN":
|
||||||
p[1] = char_to_bytevalue(p[1]) # character literals are converted to byte value.
|
|
||||||
elif tok.type == "BOOLEAN":
|
|
||||||
p[1] = int(p[1]) # boolean literals are converted to integer form (true=1, false=0).
|
p[1] = int(p[1]) # boolean literals are converted to integer form (true=1, false=0).
|
||||||
p[0] = LiteralValue(value=p[1], sourceref=_token_sref(p, 1))
|
p[0] = LiteralValue(value=p[1], sourceref=_token_sref(p, 1))
|
||||||
|
|
||||||
@ -1659,7 +1657,6 @@ def p_empty(p):
|
|||||||
|
|
||||||
def p_error(p):
|
def p_error(p):
|
||||||
stack_state_str = ' '.join([symbol.type for symbol in parser.symstack][1:])
|
stack_state_str = ' '.join([symbol.type for symbol in parser.symstack][1:])
|
||||||
print('\n[ERROR DEBUG: parser state={:d} stack: {} . {} ]'.format(parser.state, stack_state_str, p))
|
|
||||||
if p:
|
if p:
|
||||||
sref = SourceRef(p.lexer.source_filename, p.lineno, find_tok_column(p))
|
sref = SourceRef(p.lexer.source_filename, p.lineno, find_tok_column(p))
|
||||||
if p.value in ("", "\n"):
|
if p.value in ("", "\n"):
|
||||||
@ -1668,6 +1665,7 @@ def p_error(p):
|
|||||||
p.lexer.error_function(sref, "syntax error before or at '{:.20s}'", str(p.value).rstrip())
|
p.lexer.error_function(sref, "syntax error before or at '{:.20s}'", str(p.value).rstrip())
|
||||||
else:
|
else:
|
||||||
lexer.error_function(None, "syntax error at end of input", lexer.source_filename)
|
lexer.error_function(None, "syntax error at end of input", lexer.source_filename)
|
||||||
|
# print('\n[ERROR DEBUG: parser state={:d} stack: {} . {} ]'.format(parser.state, stack_state_str, p))
|
||||||
|
|
||||||
|
|
||||||
def _token_sref(p, token_idx):
|
def _token_sref(p, token_idx):
|
||||||
|
@ -252,13 +252,13 @@ def test_char_string():
|
|||||||
result = parse_source(test_source_4)
|
result = parse_source(test_source_4)
|
||||||
block = result.scope.nodes[0]
|
block = result.scope.nodes[0]
|
||||||
var1, var2, var3, assgn1, assgn2, assgn3, = block.scope.nodes
|
var1, var2, var3, assgn1, assgn2, assgn3, = block.scope.nodes
|
||||||
assert var1.value.value == 64
|
assert var1.value.value == '@'
|
||||||
assert var2.value.value == 126
|
assert var2.value.value == 'π'
|
||||||
assert var3.value.value == "abc"
|
assert var3.value.value == "abc"
|
||||||
assert assgn1.right.value == 64
|
assert assgn1.right.value == '@'
|
||||||
assert assgn2.right.value == 126
|
assert assgn2.right.value == 'π'
|
||||||
assert assgn3.right.value == "abc"
|
assert assgn3.right.value == "abc"
|
||||||
|
# note: the actual one-charactor-to-bytevalue conversion is done at the very latest, when issuing an assignment statement
|
||||||
|
|
||||||
|
|
||||||
test_source_5 = """
|
test_source_5 = """
|
||||||
|
9
todo.ill
9
todo.ill
@ -1,12 +1,7 @@
|
|||||||
%output basic
|
|
||||||
%import c64lib
|
|
||||||
|
|
||||||
~ main {
|
~ main {
|
||||||
|
|
||||||
var .float flt
|
var .float flt = -9.87e-21
|
||||||
var bytevar = 22 + 23 ; @todo bytevar in source should show its initial value in a comment
|
var bytevar = 22 + 23
|
||||||
var .text guess1 = "?X" * 40 ; @todo constant-fold before semantic check
|
|
||||||
var .text guess2 = "?" * 40 ; @todo string result instead of int!
|
|
||||||
const .word border = $d020
|
const .word border = $d020
|
||||||
var .word border2 = $d020
|
var .word border2 = $d020
|
||||||
memory screenm = $d021
|
memory screenm = $d021
|
||||||
|
Loading…
Reference in New Issue
Block a user