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
2023-05-10 16:21:37 +0200
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
ea2eee1ef9dd3d8a98b96957d8bfb9733a5e0ef7
ea2eee1e
1 parent
608dcc1a
ttc run: added let, Python expr to print and assert
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
46 additions
and
43 deletions
ttc/run.py
ttc/run.py
View file @
ea2eee1
...
...
@@ -179,37 +179,6 @@ class Runner (object) :
args
.
append
(
f
"=> {_val(ret)}"
)
return
(
f
"{F.WHITE}{event}"
,
*
args
)
class
AssertEnv
(
dict
)
:
def
__init__
(
self
,
ttc
,
*
l
,
**
k
)
:
super
()
.
__init__
(
*
l
,
**
k
)
self
.
ttc
=
ttc
def
__getitem__
(
self
,
key
)
:
if
not
isinstance
(
key
,
str
)
:
raise
TypeError
(
f
"expected 'str' key, got {type(key).__name__!r}"
)
key
=
key
.
upper
()
if
(
reg
:
=
regnum
.
get
(
key
,
None
))
is
not
None
:
return
self
.
ttc
.
cpu
.
reg
[
reg
]
elif
key
==
"INTR"
:
return
list
(
self
.
ttc
.
cpu
.
intr
)
elif
key
==
"MASK"
:
MR
=
self
.
ttc
.
cpu
.
reg
[
regnum
[
"MR"
]]
return
[
int
(
m
)
for
m
in
bin
(
MR
)[
2
:]
.
rjust
(
16
,
"1"
)]
elif
key
==
"CLOCK"
:
return
self
.
ttc
.
cpu
.
clock
elif
key
.
startswith
(
"["
)
and
key
.
endswith
(
"]"
)
:
addr
=
key
[
1
:
-
1
]
if
":"
in
addr
:
start
,
stop
=
addr
.
split
(
":"
,
1
)
start
=
int
(
start
or
"0"
,
16
)
stop
=
int
(
stop
or
"FFFF"
,
16
)
return
list
(
self
.
ttc
.
ram
.
ram
[
start
:
stop
+
1
])
else
:
return
self
.
ttc
.
ram
.
ram
[
int
(
addr
,
16
)]
elif
key
==
"SCREEN"
:
return
self
.
ttc
.
screen
.
ascii
()
else
:
raise
KeyError
(
key
)
class
ShellRunner
(
Runner
)
:
_prompt
=
"ttc >>>"
prompt
=
f
"{S.BRIGHT}{_prompt}{S.RESET_ALL} "
...
...
@@ -223,6 +192,7 @@ class ShellRunner (Runner) :
readline
.
set_completer
(
self
.
complete
)
self
.
script
=
self
.
parse_script
(
script
)
self
.
interactive
=
interactive
self
.
eval_env
=
{}
def
err
(
self
,
msg
)
:
if
self
.
interactive
:
super
()
.
err
(
msg
)
...
...
@@ -362,6 +332,36 @@ class ShellRunner (Runner) :
else
:
await
self
.
sim
.
ui_expect
(
*
args
)
return
False
async
def
cmd_let
(
self
,
name
:
str
,
expr
:
str
=
None
)
:
"""saves a value as a name
- name: name to be assigned
- expr: value expression as a Python expression involving
- the names already assigned with let
- registers names
- the interrupt vector INTR (list of 0/1)
- the interrupt mask MASK (list of 0/1)
- the clock tick counter CLOCK
- the memory RAM (list of ints)
- the screen text SCREEN (str)
"""
if
expr
is
None
:
self
.
eval_env
.
pop
(
name
,
None
)
else
:
self
.
eval_env
[
name
]
=
self
.
eval
(
expr
)
def
eval
(
self
,
expr
,
loc
=
{})
:
try
:
return
int
(
expr
,
16
)
except
:
env
=
self
.
eval_env
.
copy
()
for
reg
,
num
in
regnum
.
items
()
:
env
[
reg
]
=
self
.
ttc
.
cpu
.
reg
[
num
]
env
[
"INTR"
]
=
list
(
self
.
ttc
.
cpu
.
intr
)
MR
=
self
.
ttc
.
cpu
.
reg
[
regnum
[
"MR"
]]
env
[
"MASK"
]
=
[
int
(
m
)
for
m
in
bin
(
MR
)[
2
:]
.
rjust
(
16
,
"1"
)]
env
[
"CLOCK"
]
=
self
.
ttc
.
cpu
.
clock
env
[
"RAM"
]
=
list
(
self
.
ttc
.
ram
.
ram
)
env
[
"SCREEN"
]
=
self
.
ttc
.
screen
.
ascii
()
return
eval
(
expr
,
env
,
loc
)
async
def
cmd_cycle
(
self
,
count
:
int
=
1
)
:
"""run one or more CPU cycle
- count: number of cycles to run
...
...
@@ -437,8 +437,8 @@ class ShellRunner (Runner) :
start
,
stop
=
addr
.
split
(
":"
,
1
)
else
:
start
=
stop
=
addr
start
=
int
(
start
or
"0"
,
16
)
stop
=
int
(
stop
or
"FFFF"
,
16
)
start
=
self
.
eval
(
start
or
"0"
)
stop
=
self
.
eval
(
stop
or
"FFFF"
)
if
start
>
stop
:
raise
ValueError
return
start
,
stop
...
...
@@ -460,19 +460,18 @@ class ShellRunner (Runner) :
async
def
cmd_assert
(
self
,
expr
:
str
,
message
:
str
=
None
)
:
"""check assertion
- expr: Python expression checked to be True, may include
- register names: the register's value
- intr: the interrupt vector as a list of 0/1
- mask: the interrupt mask (MR) as a list of 0/1
- clock: the clock counter
- screen: the text on screen (without colours)
- [ADDR]: the value in RAM at ADDR
- [ADDR:ADDR]: the list of values in RAM in specified range (inclusive)
- the names assigned with let
- registers names
- the interrupt vector INTR (list of 0/1)
- the interrupt mask MASK (list of 0/1)
- the clock tick counter CLOCK
- the memory RAM (list of ints)
- the screen text SCREEN
- [message]: a message to be printed if assertion fails
"""
global
CLIRET
env
=
AssertEnv
(
self
.
ttc
)
try
:
ret
=
eval
(
expr
,
env
)
ret
=
self
.
eval
(
expr
)
except
Exception
as
err
:
print
(
f
"{F.RED}{S.BRIGHT}assert error:{S.RESET_ALL}"
f
" {F.BLUE}{expr}{F.RESET} raised"
,
...
...
@@ -496,7 +495,11 @@ class ShellRunner (Runner) :
- screen: text screen
"""
for
comp
in
component
:
if
(
reg
:
=
comp
.
upper
())
in
regnum
:
if
comp
in
self
.
eval_env
:
print
(
f
"{F.GREEN}{comp}{F.RESET}"
f
" = {F.BLUE}{self.eval_env[comp]}"
f
"{S.RESET_ALL}"
)
elif
(
reg
:
=
comp
.
upper
())
in
regnum
:
num
=
regnum
[
reg
]
print
(
f
"{F.GREEN}{reg}{F.RESET}"
f
" = {F.BLUE}{_val(self.ttc.cpu.reg[num])}"
...
...
Please
register
or
login
to post a comment