Skip to content

Commit 1e41280

Browse files
committed
Adding propper logging rather than just print statements.
On branch dev-messages Changes to be committed: modified: Makefile modified: compile.py modified: pyucode/UCProgram.py modified: pyucode/UCResolver.py modified: pyucode/UCState.py
1 parent de3e4cb commit 1e41280

File tree

5 files changed

+143
-106
lines changed

5 files changed

+143
-106
lines changed

Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ ifdef DOT
2222
CC_FLAGS += --flowgraph --graphpath work/graph.dot
2323
endif
2424

25+
ifdef VERBOSE
26+
CC_FLAGS += --verbose
27+
endif
28+
2529
ifdef DEBUG
2630
CC_FLAGS += --debug-states
2731
endif

compile.py

+100-72
Original file line numberDiff line numberDiff line change
@@ -3,81 +3,109 @@
33
import os
44
import sys
55
import argparse
6-
import logging as log
6+
import logging
77

88
import pyucode as ucode
99

10-
def parseArguments():
11-
"""
12-
parse all command line arguments to the program.
13-
"""
14-
parser = argparse.ArgumentParser(description=__doc__)
15-
parser.add_argument("program",help="The program to compile.")
16-
parser.add_argument("--output","-O",help="Output path", default="out.v")
17-
parser.add_argument("--gendocs","-D", help="Generate documentation",
18-
action="store_true")
19-
parser.add_argument("--instrdocs",
20-
help="Instruction documentation output file path",
21-
default = "doc-instrs.html")
22-
parser.add_argument("--progdocs",
23-
help="Program documentation output file path",
24-
default = "doc-program.html")
25-
parser.add_argument("--debug-states", help="Display the current state each\
26-
simulation cycle.",action="store_true")
27-
parser.add_argument("--flowgraph", help="Emit a graph of program control\
28-
flow changes.",action="store_true")
29-
parser.add_argument("--graphpath", help="Path of file created when \
30-
--flowgraph is set.",default="flow.dot")
31-
parser.add_argument("--opt-coalesce",
32-
help="Enable coalecsing of blocks to improve performance.",
33-
action="store_true")
34-
35-
args = parser.parse_args()
36-
return args
37-
38-
def main():
39-
"""
40-
Main entry point for the program
41-
"""
42-
args = parseArguments()
43-
44-
print("---------- uCode Compiler ----------")
45-
print("> Loading sources")
46-
47-
program = ucode.UCProgram()
48-
program.parseSource(args.program)
49-
50-
print("> Resolving objects")
51-
52-
resolver = ucode.UCResolver()
53-
resolver.addVariables(program.variables)
54-
resolver.addInstructions(program.instructions)
55-
resolver.addProgram(program)
56-
resolver.enable_coalescing = args.opt_coalesce
57-
resolver.resolve()
58-
59-
print("> Rendering template to %s" % args.output)
60-
61-
renderer = ucode.UCTemplater(resolver)
62-
renderer.debug_states = args.debug_states
63-
renderer.renderTo(args.output)
64-
65-
# Generate per-program documentation
66-
progdocs = ucode.UCProgramDocgen(resolver)
67-
68-
if(args.gendocs):
69-
print("> Rendering instruction documentation to %s" % args.instrdocs)
70-
dg = ucode.UCInstructionDocGen(resolver.instrs)
71-
dg.renderTo(args.instrdocs)
10+
class Program(object):
11+
12+
def __init__(self):
13+
"""
14+
Create a new program object.
15+
"""
16+
self.log = logging.getLogger(__name__)
17+
18+
19+
def configureLogging(self,args):
20+
"""
21+
Setup all of the logging / info message defaults.
22+
"""
23+
if(args.verbose):
24+
self.log.setLevel(logging.INFO)
25+
logging.basicConfig(level=logging.INFO)
26+
else:
27+
self.log.setLevel(logging.WARNING)
28+
logging.basicConfig(level=logging.WARNING)
29+
30+
31+
def parseArguments(self):
32+
"""
33+
parse all command line arguments to the program.
34+
"""
35+
parser = argparse.ArgumentParser(description=__doc__)
36+
parser.add_argument("program",help="The program to compile.")
37+
parser.add_argument("--output","-O",help="Output path", default="out.v")
38+
parser.add_argument("--gendocs","-D", help="Generate documentation",
39+
action="store_true")
40+
parser.add_argument("--instrdocs",
41+
help="Instruction documentation output file path",
42+
default = "doc-instrs.html")
43+
parser.add_argument("--progdocs",
44+
help="Program documentation output file path",
45+
default = "doc-program.html")
46+
parser.add_argument("--debug-states", help="Display the current state each\
47+
simulation cycle.",action="store_true")
48+
parser.add_argument("--flowgraph", help="Emit a graph of program control\
49+
flow changes.",action="store_true")
50+
parser.add_argument("--graphpath", help="Path of file created when \
51+
--flowgraph is set.",default="flow.dot")
52+
parser.add_argument("--opt-coalesce",
53+
help="Enable coalecsing of blocks to improve performance.",
54+
action="store_true")
55+
parser.add_argument("--verbose", "-v", action="store_true",
56+
help="Be verbose when displaying messages")
57+
58+
args = parser.parse_args()
59+
return args
60+
61+
def main(self):
62+
"""
63+
Main entry point for the program
64+
"""
65+
args = self.parseArguments()
66+
self.configureLogging(args)
67+
68+
self.log.info("---------- uCode Compiler ----------")
69+
self.log.info("> Loading sources")
70+
71+
program = ucode.UCProgram()
72+
program.parseSource(args.program)
7273

73-
print("> Rendering program documentation to %s" % args.progdocs)
74-
progdocs.gen_program_docs(args.progdocs)
75-
76-
if(args.flowgraph):
77-
print("> Writing flow graph to '%s'" % args.graphpath)
78-
progdocs.gen_flow_dot_graph(args.graphpath)
79-
80-
print("> Done")
74+
self.log.info("> Resolving objects")
75+
76+
resolver = ucode.UCResolver()
77+
resolver.addVariables(program.variables)
78+
resolver.addInstructions(program.instructions)
79+
resolver.addProgram(program)
80+
resolver.enable_coalescing = args.opt_coalesce
81+
resolver.resolve()
82+
83+
self.log.info("> Rendering template to %s" % args.output)
84+
85+
renderer = ucode.UCTemplater(resolver)
86+
renderer.debug_states = args.debug_states
87+
renderer.renderTo(args.output)
88+
89+
# Generate per-program documentation
90+
progdocs = ucode.UCProgramDocgen(resolver)
91+
92+
if(args.gendocs):
93+
self.log.info("> Rendering instruction documentation to %s" % args.instrdocs)
94+
dg = ucode.UCInstructionDocGen(resolver.instrs)
95+
dg.renderTo(args.instrdocs)
96+
97+
self.log.info("> Rendering program documentation to %s" % args.progdocs)
98+
progdocs.gen_program_docs(args.progdocs)
99+
100+
if(args.flowgraph):
101+
self.log.info("> Writing flow graph to '%s'" % args.graphpath)
102+
progdocs.gen_flow_dot_graph(args.graphpath)
103+
104+
self.log.info("> Done")
105+
return 0
106+
81107

82108
if(__name__ == "__main__"):
83-
main()
109+
p = Program()
110+
sys.exit(p.main())
111+

pyucode/UCProgram.py

+19-17
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import os
88
import sys
99
import copy
10-
import logging as log
10+
import logging
1111

1212
from .UCInstructions import UCInstructionCollection
1313

@@ -35,6 +35,7 @@ def __init__(self, src):
3535
"""
3636
Create a new program flow change object from source.
3737
"""
38+
self.log = logging.getLogger(__name__)
3839
self.src=src
3940
self.change_type = UCProgramFlowNone
4041
self.target = None
@@ -51,7 +52,7 @@ def parse(self):
5152
tokens = self.src.split(" ")
5253

5354
if(len(tokens) <= 1):
54-
log.error("Control flow change without target")
55+
self.log.error("Control flow change without target")
5556

5657
if(tokens[0] == "goto"):
5758
self.change_type = UCProgramFlowGoto
@@ -82,6 +83,7 @@ def __init__(self, name, statements, flow_change):
8283
Create a new program block with the supplied statments and control
8384
flow change at the end.
8485
"""
86+
self.log = logging.getLogger(__name__)
8587
self.name = name
8688
self.statements = statements
8789
self.flow_change = flow_change
@@ -162,7 +164,7 @@ def atomised(self):
162164
tr.append(newblock)
163165
namecounter += 1
164166

165-
print("Atomised block '%s' into %d sub-blocks" %
167+
self.log.info("Atomised block '%s' into %d sub-blocks" %
166168
(self.name, len(tr)))
167169

168170
return tr
@@ -178,6 +180,7 @@ def __init__(self):
178180
"""
179181
Create a new, empty program.
180182
"""
183+
self.log = logging.getLogger(__name__)
181184
self.block_count = 0
182185

183186
self.blocks = []
@@ -245,7 +248,7 @@ def synth_flowchanges(self, block):
245248
elif(flow_change.change_type == UCProgramFlowIfNez):
246249
cmp_type = " != 0"
247250
else:
248-
log.error("Unknown conditional jump type")
251+
self.log.error("Unknown conditional jump type")
249252

250253
if(is_first):
251254
tree.append("if ( %s %s )" %
@@ -313,15 +316,15 @@ def addProgramBlock(self, new_block):
313316
self.blocks_by_name[block.name]=block
314317
self.block_count = self.block_count + 1
315318
else:
316-
log.error("The block with name '%s' has already been declared"% block.name)
319+
self.log.error("The block with name '%s' has already been declared"% block.name)
317320

318321

319322
def addProgramVariable(self, lineNo,tokens):
320323
"""
321324
Add a Program Variable parsed from a program file on the given line.
322325
"""
323326
if(len(tokens) < 2):
324-
log.error("Line %d: Bad Variable declaration: '%s'\n\t"
327+
self.log.error("Line %d: Bad Variable declaration: '%s'\n\t"
325328
% (" ".join(tokens),lineNo))
326329

327330
name = "name not found"
@@ -371,23 +374,23 @@ def handleInclude(self,line_no, line_tokens, current_file):
371374
assert (line_tokens[0] == "using"), "First element of line_tokens should be 'using'"
372375

373376
if ( len(line_tokens) < 3 ):
374-
log.error("Bad 'using' statement on line %d" % line_no)
375-
log.error("Should be of the form 'using [instructions|subprogram] 'filepath'")
377+
self.log.error("Bad 'using' statement on line %d" % line_no)
378+
self.log.error("Should be of the form 'using [instructions|subprogram] 'filepath'")
376379

377380
base = os.path.dirname(current_file)
378381
filepath = "".join(line_tokens[2:]).lstrip("'\"").rstrip("'\"")
379382
filepath = os.path.join(base,filepath)
380383

381384
if(line_tokens[1] == "instructions"):
382-
log.info("Parsing instructions file: '%s'" % filepath)
385+
self.log.info("Parsing instructions file: '%s'" % filepath)
383386
self.instructions.parse(filepath)
384387

385388
elif(line_tokens[1] == "subprogram"):
386-
log.info("Parsing subprogram file: '%s'" % filepath)
389+
self.log.info("Parsing subprogram file: '%s'" % filepath)
387390
self.parseSource(filepath)
388391

389392
else:
390-
log.error("unknown using directive '%s', should be 'instructions' or 'subprogram'" % line_tokens[1])
393+
self.log.error("unknown using directive '%s', should be 'instructions' or 'subprogram'" % line_tokens[1])
391394

392395

393396
def parseSource(self, filepath):
@@ -427,7 +430,7 @@ def l_add_current_block(current_name,
427430
toadd = UCProgramBlock(current_name,
428431
current_statements,
429432
current_flowchange)
430-
print("Add block '%s'" % current_name)
433+
self.log.info("Add block '%s'" % current_name)
431434
self.addProgramBlock(toadd)
432435

433436

@@ -488,15 +491,14 @@ def l_add_current_block(current_name,
488491
elif(tokens[0] in ["goto", "ifeqz", "ifnez"]):
489492
current_flowchange.append(UCProgramFlowChange(line))
490493
elif(tokens[0] == "port"):
491-
log.error("Line %d: Cannot put port declarations inside blocks." % lno)
494+
self.log.error("Line %d: Cannot put port declarations inside blocks." % lno)
492495
elif(tokens[0] == "state"):
493-
log.error("Line %d: Cannot put state delcarations inside blocks." % lno)
496+
self.log.error("Line %d: Cannot put state delcarations inside blocks." % lno)
494497
else:
495498
current_statements.append(line)
496499

497500
else:
498-
print("Parse error on line %d" % (lno + 1))
499-
print(line)
501+
self.log.error("Parse error on line %d: %s" % (lno + 1, line))
500502
break
501503

502504
if(current_name != None and
@@ -514,4 +516,4 @@ def l_add_current_block(current_name,
514516
program.parseSource(sys.argv[1])
515517

516518
for block in program.blocks:
517-
print("- %s" % block.name)
519+
self.log.info("- %s" % block.name)

0 commit comments

Comments
 (0)