Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Franck Pommereau
/
ttc.js
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Franck Pommereau
2024-04-06 15:55:58 +0200
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
40541df03b4cb863bfaa854ea1bba720cdc826df
40541df0
1 parent
bfcf40f9
done exam (untested)
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
195 additions
and
11 deletions
ttc/exam.py
ttc/vat.c
ttc/vat.pyx
ttc/words.py
ttc/exam.py
View file @
40541df
...
...
@@ -8,7 +8,14 @@ import string as S
from
collections.abc
import
Iterable
from
pathlib
import
Path
from
.asm
import
asm
from
rich.progress
import
track
as
rich_track
from
pygments.lexer
import
RegexLexer
from
pygments.token
import
Name
,
Keyword
,
Number
,
Text
,
Comment
,
String
from
pygments.formatters
import
LatexFormatter
from
pygments
import
highlight
from
.asm
import
asm
,
Preprocessor
,
stdlib
from
.
import
cpuinfo
as
cnfo
from
.vat
import
TTC
,
AsmError
from
.
import
words
as
W
...
...
@@ -38,6 +45,19 @@ class Func:
env
.
update
(
zip
(
self
.
args
,
args
))
return
self
.
eval
(
self
.
expr
,
env
)
def
sub
(
self
,
repl
):
rex
=
re
.
compile
(
fr
"([
\"\'
])({'|'.join(repl)})
\1
"
,
re
.
I
)
def
sub
(
match
):
return
(
match
.
group
(
1
)
+
repl
[
match
.
group
(
2
)
.
upper
()]
+
match
.
group
(
1
))
return
self
.
__class__
(
self
.
name
,
self
.
args
,
rex
.
sub
(
sub
,
self
.
expr
),
self
.
_env
)
@classmethod
def
env
(
cls
,
extra
=
{},
**
more
):
env
=
dict
(
cls
.
_builtins
)
...
...
@@ -56,7 +76,7 @@ class Func:
class
Source
:
_pyrun
=
re
.
compile
(
r"\s*\#\s*\>\>\>\s*(.+)$"
)
_subst
=
re
.
compile
(
r"\{\{(.+)\}\}
$
"
)
_subst
=
re
.
compile
(
r"\{\{(.+)\}\}"
)
_meta
=
{
"func"
:
re
.
compile
(
r"^\s*\#\s*(\w+)\s+([\w\s,]*)=>(.+)$"
),
"expr"
:
re
.
compile
(
r"^\s*\#\s*(\w+)\s*=\s*(.+)$"
),
"text"
:
re
.
compile
(
r"^\s*\#\s*(\w+)\s*:\s*(.+)$"
),
...
...
@@ -94,7 +114,7 @@ class Source:
else
:
new
=
str
(
new
)
line
=
line
.
replace
(
match
.
group
(
0
),
new
)
self
.
src
.
append
(
line
)
self
.
src
.
append
(
line
.
rstrip
()
)
continue
g
=
match
.
groups
()
if
kind
==
"expr"
:
...
...
@@ -127,12 +147,39 @@ class Source:
for
lno
,
line
in
enumerate
(
stream
,
start
=
1
):
yield
lno
,
line
.
rstrip
()
def
copy
(
self
,
src
=
[]):
cls
=
self
.
__class__
new
=
cls
.
__new__
(
cls
)
new
.
meta
=
dict
(
self
.
meta
)
new
.
src
=
src
or
self
.
src
[:]
new
.
lno
=
dict
(
self
.
lno
)
new
.
onl
=
dict
(
self
.
onl
)
new
.
_ttc
=
None
return
new
@property
def
ttc
(
self
):
if
self
.
_ttc
is
None
:
self
.
_ttc
=
TTC
()
return
self
.
_ttc
def
source
(
self
,
hide
=
{}):
lines
=
[]
for
onl
,
lin
in
enumerate
(
self
.
src
,
start
=
1
):
lno
=
self
.
lno
[
onl
]
sub
=
hide
.
get
(
lno
,
None
)
tab
=
" "
*
(
len
(
lin
)
-
len
(
lin
.
lstrip
()))
if
sub
is
None
:
lines
.
append
(
lin
)
elif
callable
(
sub
):
lines
.
append
(
sub
(
lno
,
lin
,
tab
))
else
:
if
not
isinstance
(
sub
,
str
):
sub
=
"{indent}# line {lno}"
env
=
dict
(
self
.
meta
,
indent
=
tab
,
lno
=
lno
)
lines
.
append
(
Func
.
eval
(
f
"f{sub!r}"
,
env
))
return
"
\n
"
.
join
(
lines
)
def
check
(
self
,
*
funcs
,
maxsteps
=
1024
,
ttc
=
None
):
if
ttc
is
None
:
ttc
=
self
.
ttc
...
...
@@ -160,3 +207,110 @@ class Source:
raise
CheckError
(
name
,
f
"raised {exc}: {err}"
)
if
not
ok
:
raise
CheckError
(
name
,
f
"failed with {ok!r}"
)
_irqx
=
re
.
compile
(
r"^irq[0-9A-F]$"
,
re
.
I
)
@property
@F.cache
def
labels
(
self
):
labels
=
set
()
tokens
=
[
ln
.
origin
.
toks
for
ln
in
Preprocessor
([{
"source"
:
self
.
source
(),
"pathname"
:
"<exam>"
}])]
for
tokline
in
tokens
:
for
tok
in
tokline
:
if
tok
.
endswith
(
":"
)
or
tok
.
startswith
(
"@"
):
lbl
=
tok
.
strip
(
"@:"
)
.
lower
()
if
not
self
.
_irqx
.
match
(
lbl
):
labels
.
add
(
lbl
.
upper
())
return
labels
def
randomize
(
self
,
names
=
W
.
animals
,
check
=
True
):
# registers
regs
=
[
r
for
r
in
cnfo
.
regname
if
r
.
startswith
(
"R"
)]
R
.
shuffle
(
regs
)
repl
=
dict
(
zip
(
cnfo
.
regname
,
regs
))
# labels
repl
.
update
(
zip
(
self
.
labels
,
R
.
sample
(
names
,
len
(
self
.
labels
))))
# rewrite code
rex
=
re
.
compile
(
fr
"
\b
({'|'.join(repl)})
\b
"
,
re
.
I
)
new
=
self
.
copy
([
rex
.
sub
(
lambda
m
:
repl
[
m
.
group
(
1
)
.
upper
()],
line
)
for
line
in
self
.
src
])
for
k
,
v
in
new
.
meta
.
items
():
if
isinstance
(
v
,
str
):
new
.
meta
[
k
]
=
rex
.
sub
(
lambda
m
:
repl
[
m
.
group
(
1
)
.
upper
()],
v
)
elif
isinstance
(
v
,
Func
):
new
.
meta
[
k
]
=
v
.
sub
(
repl
)
if
check
:
new
.
check
()
return
repl
,
new
class
SourcePool
:
def
__init__
(
self
,
paths
,
chk
=
{},
verbose
=
True
):
self
.
src
=
[]
if
verbose
:
self
.
_track
=
rich_track
for
p
in
self
.
_track
(
paths
,
transient
=
True
,
description
=
"Loading TTC sources"
):
self
.
src
.
append
(
Source
(
p
,
**
chk
))
def
_track
(
self
,
items
,
**
_
):
return
items
def
pick
(
self
,
rand
=
{}):
return
R
.
choice
(
self
.
src
)
.
randomize
(
**
rand
)
macros
=
set
()
for
line
in
(
ln
.
strip
()
for
ln
in
stdlib
.
splitlines
()):
toks
=
line
.
split
()
if
toks
and
toks
[
0
]
==
"
%
def"
:
macros
.
add
(
toks
[
1
])
class
TTCLexer
(
RegexLexer
):
name
=
"TTC"
aliases
=
[
"ttc"
]
filenames
=
[
"*.ttc"
]
flags
=
re
.
I
tokens
=
{
"root"
:
[
(
r"\s+"
,
Text
),
(
r"#.*\n"
,
Comment
.
Single
),
(
r"
%.*
\n"
,
Comment
.
Preproc
),
(
r"\$\S+"
,
Name
.
Variable
),
(
r"@\S+"
,
Name
.
Label
),
(
r"\S+:"
,
Name
.
Label
),
(
fr
"
\b
({'|'.join(cnfo.parameters)})
\b
"
,
Keyword
.
Reserved
),
(
fr
"
\b
({'|'.join(macros)})
\b
"
,
Name
.
Function
),
(
fr
"
\b
({'|'.join(cnfo.regname)})
\b
"
,
Name
.
Attribute
),
(
r"[0-9A-F]+"
,
Number
),
(
r'"[^"]*"'
,
String
),
(
r"'[^']*'"
,
String
),
]
}
class
Pygmentize
:
def
__init__
(
self
,
fmt
=
LatexFormatter
):
self
.
lexer
=
TTCLexer
()
self
.
formatter
=
fmt
()
@F.cache
def
__call__
(
self
,
source
,
single
=
False
,
**
opt
):
if
isinstance
(
source
,
str
):
src
=
source
elif
isinstance
(
source
,
(
tuple
,
list
)):
src
=
" "
.
join
(
str
(
t
)
for
t
in
source
)
elif
isinstance
(
source
,
Source
):
src
=
source
.
source
(
**
opt
)
else
:
raise
ValueError
(
"invalid HRM source"
)
pyg
=
highlight
(
src
,
self
.
lexer
,
self
.
formatter
)
if
single
:
lines
=
pyg
.
splitlines
()
return
" "
.
join
(
lines
[
1
:
-
1
])
else
:
return
pyg
...
...
ttc/vat.c
View file @
40541df
This diff could not be displayed because it is too large.
ttc/vat.pyx
View file @
40541df
from libc.stdlib cimport
srand,
rand
from libc.stdlib cimport rand
from libc.time cimport time
from cython cimport view
...
...
@@ -10,8 +10,6 @@ from rich.text import Text
from rich.color import Color
from rich.style import Style
srand(<unsigned int>time(NULL))
cdef word[16] INTR = [ # i => bit i
0b0000000000000001,
0b0000000000000010,
...
...
@@ -80,6 +78,18 @@ class AsmError(Exception):
super().__init__("assembly error")
self.errors = errors
def print(self):
for line, errors in self.errors.items():
last = None
for ln in line.backtrace():
if last is None:
rprint(Text(f"{ln.path}:{ln.lno}", "red"))
elif (ln.path, ln.lno) != last:
rprint(Text(f" from {ln.path}:{ln.lno}", "dim"))
last = (ln.path, ln.lno)
for err in errors:
rprint(Text(" >>", "yellow"), Text(err))
cdef list FG = [Color.from_ansi(15),
Color.from_ansi(0),
...
...
@@ -604,3 +614,28 @@ cdef class TTC:
if ip in labels:
rprint(f"[dim magenta]{' '.join(sorted(labels[ip]))}:")
ip = self.print(ip, print_regs=False, print_irq=False, ram=ram)
def __getitem__(self, key):
cdef int start, stop, step
if isinstance(key, str):
return self.ram[<int>self.labels[key]]
elif isinstance(key, slice):
if key.start is None:
start = 0
elif isinstance(key.start, str):
start = self.labels[key.start]
else:
start = key.start
if key.stop is None:
stop = len(self.ram)
elif isinstance(key.stop, str):
stop = self.labels[key.stop]
else:
stop = key.stop
if key.step is None:
step = 1
else:
step = key.step
return self.ram[start:stop:step]
else:
return self.ram[<int>key]
...
...
ttc/words.py
View file @
40541df
...
...
@@ -6125,7 +6125,6 @@ words = [
"halogen"
,
"haloing"
,
"halon"
,
"halt"
,
"halted"
,
"halter"
,
"halting"
,
...
...
@@ -10154,7 +10153,6 @@ words = [
"pontiff"
,
"pontoon"
,
"pony"
,
"pop"
,
"popcorn"
,
"pope"
,
"poplar"
,
...
...
@@ -10524,7 +10522,6 @@ words = [
"pursuit"
,
"purvey"
,
"purview"
,
"push"
,
"pushed"
,
"pusher"
,
"pushier"
,
...
...
@@ -11118,7 +11115,6 @@ words = [
"resend"
,
"resent"
,
"reserve"
,
"reset"
,
"reside"
,
"resided"
,
"residue"
,
...
...
@@ -12053,7 +12049,6 @@ words = [
"servo"
,
"sesame"
,
"session"
,
"set"
,
"setback"
,
"settee"
,
"setter"
,
...
...
Please
register
or
login
to post a comment