1
|
1 import hashlib
|
|
2 # Import compiler components:
|
|
3 from . import lexer
|
5
|
4 from .parser import Parser
|
1
|
5 from .codegenerator import CodeGenerator
|
|
6 from .nodes import ExportedSymbol
|
7
|
7 from .errors import CompilerException
|
1
|
8
|
|
9 class Compiler:
|
|
10 versie = '0.9.3'
|
|
11
|
|
12 def __repr__(self):
|
|
13 return 'LCFOS compiler {0}'.format(self.versie)
|
|
14
|
|
15 def generateSignature(self, src):
|
|
16 return hashlib.md5(bytes(src,encoding='ascii')).hexdigest()
|
|
17
|
|
18 def compilesource(self, src):
|
|
19 """ Front end that handles the stages: """
|
6
|
20 self.errorlist = []
|
5
|
21 # Pass 1: parsing and type checking
|
1
|
22 tokens = lexer.tokenize(src) # Lexical stage
|
5
|
23 p = Parser(tokens)
|
7
|
24 try:
|
|
25 ast = p.parseModule() # Parse a module
|
|
26 except CompilerException as e:
|
|
27 p.errorlist.append( (e.row, e.col, e.msg) )
|
5
|
28 if len(p.errorlist) > 0:
|
|
29 self.errorlist = p.errorlist
|
|
30 return
|
|
31 # Pass 2: code generation
|
1
|
32 CodeGenerator().generatecode(ast)
|
|
33 # Attach a signature:
|
|
34 ast.signature = self.generateSignature(src)
|
|
35 # Generate exported symbols:
|
|
36 ast.exports = []
|
|
37 for proc in ast.procs:
|
|
38 if proc.public:
|
|
39 sym = ExportedSymbol(proc.name, proc.typ)
|
|
40 sym.imageoffset = proc.entrypoint
|
|
41 ast.exports.append(sym)
|
|
42 return ast
|
|
43
|
15
|
44 def compileProject(self, project):
|
|
45 mods = []
|
|
46 for fname in project.files:
|
|
47 print('Compiling {0}...'.format(fname))
|
|
48 source = project.loadProjectFile(fname)
|
|
49 mod = self.compilesource(source)
|
|
50 mods.append(mod)
|
|
51 return mods
|
|
52
|