| 1 |
2 |
jondawson |
__author__ = "Jon Dawson"
|
| 2 |
|
|
__copyright__ = "Copyright (C) 2012, Jonathan P Dawson"
|
| 3 |
|
|
__version__ = "0.1"
|
| 4 |
|
|
|
| 5 |
4 |
jondawson |
import struct
|
| 6 |
|
|
from copy import copy
|
| 7 |
|
|
|
| 8 |
2 |
jondawson |
from parse_tree import *
|
| 9 |
|
|
from tokens import Tokens
|
| 10 |
|
|
from allocator import Allocator
|
| 11 |
|
|
|
| 12 |
4 |
jondawson |
types = ["float", "signed", "unsigned", "short", "long", "char", "int", "void"]
|
| 13 |
|
|
numeric_types = ["float", "signed", "unsigned", "short", "long", "char", "int"]
|
| 14 |
|
|
storage_specifiers = ["const"]
|
| 15 |
|
|
|
| 16 |
2 |
jondawson |
class Parser:
|
| 17 |
|
|
|
| 18 |
|
|
"""Turn the C input file into a tree of expressions and statements."""
|
| 19 |
|
|
|
| 20 |
|
|
def __init__(self, input_file, reuse, initialize_memory):
|
| 21 |
|
|
self.scope = {}
|
| 22 |
|
|
self.function = None
|
| 23 |
|
|
self.loop = None
|
| 24 |
|
|
self.tokens = Tokens(input_file)
|
| 25 |
|
|
self.allocator = Allocator(reuse)
|
| 26 |
|
|
self.structs = []
|
| 27 |
|
|
self.initialize_memory = initialize_memory
|
| 28 |
|
|
|
| 29 |
|
|
def parse_process(self):
|
| 30 |
|
|
process = Process()
|
| 31 |
|
|
process.allocator = self.allocator
|
| 32 |
|
|
process.inputs = []
|
| 33 |
|
|
process.outputs = []
|
| 34 |
|
|
process.functions = []
|
| 35 |
|
|
while not self.tokens.end():
|
| 36 |
|
|
if self.tokens.peek() == "struct":
|
| 37 |
|
|
self.parse_define_struct()
|
| 38 |
|
|
elif self.tokens.peek() == "typedef":
|
| 39 |
|
|
self.parse_typedef_struct()
|
| 40 |
|
|
else:
|
| 41 |
|
|
process.functions.append(self.parse_function())
|
| 42 |
|
|
process.main = self.main
|
| 43 |
|
|
return process
|
| 44 |
|
|
|
| 45 |
|
|
def parse_type_specifier(self):
|
| 46 |
|
|
type_specifiers = []
|
| 47 |
|
|
|
| 48 |
4 |
jondawson |
while self.tokens.peek() in types + self.structs + storage_specifiers:
|
| 49 |
2 |
jondawson |
type_specifiers.append(self.tokens.get())
|
| 50 |
|
|
|
| 51 |
|
|
signed = True
|
| 52 |
|
|
if "unsigned" in type_specifiers:
|
| 53 |
|
|
signed = False
|
| 54 |
|
|
if "signed" in type_specifiers:
|
| 55 |
|
|
self.tokens.error("Cannot be signed and unsigned")
|
| 56 |
|
|
|
| 57 |
|
|
size = 2
|
| 58 |
|
|
if "long" in type_specifiers:
|
| 59 |
|
|
if "short" in type_specifiers:
|
| 60 |
|
|
self.tokens.error("Cannot be long and short")
|
| 61 |
|
|
size = 4
|
| 62 |
|
|
|
| 63 |
|
|
type_ = "int"
|
| 64 |
|
|
for i in type_specifiers:
|
| 65 |
|
|
if i in self.structs:
|
| 66 |
|
|
type_ = i
|
| 67 |
|
|
size = 2
|
| 68 |
|
|
signed = False
|
| 69 |
|
|
|
| 70 |
4 |
jondawson |
if "float" in type_specifiers:
|
| 71 |
|
|
if "short" in type_specifiers:
|
| 72 |
|
|
self.tokens.error("Float cannot be short")
|
| 73 |
|
|
if "long" in type_specifiers:
|
| 74 |
|
|
self.tokens.error("Float cannot be long (but double can)")
|
| 75 |
|
|
if "unsigned" in type_specifiers:
|
| 76 |
|
|
self.tokens.error("Float cannot be unsigned")
|
| 77 |
|
|
type_ = "float"
|
| 78 |
|
|
size = 4
|
| 79 |
|
|
signed = True
|
| 80 |
|
|
|
| 81 |
|
|
const = False
|
| 82 |
|
|
if "const" in type_specifiers:
|
| 83 |
|
|
const = True
|
| 84 |
|
|
|
| 85 |
2 |
jondawson |
if "void" in type_specifiers:
|
| 86 |
|
|
type_ = "void"
|
| 87 |
|
|
size = 2
|
| 88 |
|
|
signed = False
|
| 89 |
|
|
|
| 90 |
|
|
|
| 91 |
4 |
jondawson |
return type_, size, signed, const
|
| 92 |
2 |
jondawson |
|
| 93 |
4 |
jondawson |
def parse_argument(self):
|
| 94 |
|
|
type_, size, signed, const = self.parse_type_specifier()
|
| 95 |
|
|
|
| 96 |
|
|
if type_ in ["void"]:
|
| 97 |
|
|
self.tokens.error("argument cannot be void")
|
| 98 |
|
|
else:
|
| 99 |
|
|
argument = self.tokens.get()
|
| 100 |
|
|
if type_ in self.structs:
|
| 101 |
|
|
declaration = self.scope[type_]
|
| 102 |
|
|
else:
|
| 103 |
|
|
if self.tokens.peek() == "[":
|
| 104 |
|
|
self.tokens.expect("[")
|
| 105 |
|
|
self.tokens.expect("]")
|
| 106 |
|
|
declaration = ArrayDeclaration(
|
| 107 |
|
|
self.allocator,
|
| 108 |
|
|
2,
|
| 109 |
|
|
type_+"[]",
|
| 110 |
|
|
type_,
|
| 111 |
|
|
size,
|
| 112 |
|
|
signed,
|
| 113 |
|
|
None,
|
| 114 |
|
|
self.initialize_memory)
|
| 115 |
|
|
else:
|
| 116 |
|
|
declaration = VariableDeclaration(
|
| 117 |
|
|
self.allocator,
|
| 118 |
|
|
None,
|
| 119 |
|
|
argument,
|
| 120 |
|
|
type_,
|
| 121 |
|
|
size,
|
| 122 |
|
|
signed,
|
| 123 |
|
|
const)
|
| 124 |
|
|
instance = declaration.instance()
|
| 125 |
|
|
self.scope[argument] = instance
|
| 126 |
|
|
return instance.reference()
|
| 127 |
|
|
|
| 128 |
2 |
jondawson |
def parse_function(self):
|
| 129 |
|
|
function = Function()
|
| 130 |
|
|
function.allocator = self.allocator
|
| 131 |
4 |
jondawson |
stored_scope = copy(self.scope)
|
| 132 |
|
|
type_, size, signed, const = self.parse_type_specifier()
|
| 133 |
2 |
jondawson |
name = self.tokens.get()
|
| 134 |
4 |
jondawson |
|
| 135 |
2 |
jondawson |
#check if it is a global declaration
|
| 136 |
|
|
if self.tokens.peek() != "(":
|
| 137 |
4 |
jondawson |
return self.parse_global_declaration(type_, size, signed, const, name)
|
| 138 |
2 |
jondawson |
|
| 139 |
|
|
#otherwise continue parsing a function
|
| 140 |
|
|
self.tokens.expect("(")
|
| 141 |
|
|
function.name = name
|
| 142 |
|
|
function.type_ = type_
|
| 143 |
|
|
function.size = size
|
| 144 |
|
|
function.signed = signed
|
| 145 |
4 |
jondawson |
|
| 146 |
|
|
function.return_address = self.allocator.new(2,
|
| 147 |
|
|
function.name+" return address")
|
| 148 |
|
|
|
| 149 |
2 |
jondawson |
if type_ != "void":
|
| 150 |
4 |
jondawson |
|
| 151 |
|
|
if type_ in self.structs:
|
| 152 |
|
|
declaration = self.scope[type_]
|
| 153 |
|
|
else:
|
| 154 |
|
|
if self.tokens.peek() == "[":
|
| 155 |
|
|
self.tokens.error(
|
| 156 |
|
|
"Functions cannot return arrays")
|
| 157 |
|
|
else:
|
| 158 |
|
|
declaration = VariableDeclaration(
|
| 159 |
|
|
self.allocator,
|
| 160 |
|
|
None,
|
| 161 |
|
|
function.name+" return value",
|
| 162 |
|
|
type_,
|
| 163 |
|
|
size,
|
| 164 |
|
|
signed,
|
| 165 |
|
|
const)
|
| 166 |
|
|
|
| 167 |
|
|
function.return_value = declaration.instance().reference()
|
| 168 |
|
|
|
| 169 |
2 |
jondawson |
function.arguments = []
|
| 170 |
|
|
while self.tokens.peek() != ")":
|
| 171 |
4 |
jondawson |
function.arguments.append(self.parse_argument())
|
| 172 |
2 |
jondawson |
if self.tokens.peek() == ",":
|
| 173 |
|
|
self.tokens.expect(",")
|
| 174 |
|
|
else:
|
| 175 |
|
|
break
|
| 176 |
4 |
jondawson |
|
| 177 |
2 |
jondawson |
self.tokens.expect(")")
|
| 178 |
|
|
self.function = function
|
| 179 |
|
|
function.statement = self.parse_statement()
|
| 180 |
|
|
if type_ != "void" and not hasattr(function, "return_statement"):
|
| 181 |
|
|
self.tokens.error("Function must have a return statement")
|
| 182 |
|
|
self.function = None
|
| 183 |
|
|
self.scope = stored_scope
|
| 184 |
|
|
self.scope[function.name] = function
|
| 185 |
|
|
#main thread is last function
|
| 186 |
|
|
self.main = function
|
| 187 |
|
|
return function
|
| 188 |
|
|
|
| 189 |
|
|
def parse_break(self):
|
| 190 |
|
|
break_ = Break()
|
| 191 |
|
|
break_.loop = self.loop
|
| 192 |
|
|
self.tokens.expect("break")
|
| 193 |
|
|
self.tokens.expect(";")
|
| 194 |
|
|
return break_
|
| 195 |
|
|
|
| 196 |
|
|
def parse_continue(self):
|
| 197 |
|
|
continue_ = Continue()
|
| 198 |
|
|
continue_.loop = self.loop
|
| 199 |
|
|
self.tokens.expect("continue")
|
| 200 |
|
|
self.tokens.expect(";")
|
| 201 |
|
|
return continue_
|
| 202 |
|
|
|
| 203 |
|
|
def parse_return(self):
|
| 204 |
|
|
return_ = Return()
|
| 205 |
|
|
return_.function = self.function
|
| 206 |
4 |
jondawson |
return_.allocator = self.allocator
|
| 207 |
2 |
jondawson |
self.function.return_statement = return_
|
| 208 |
|
|
self.tokens.expect("return")
|
| 209 |
|
|
if hasattr(self.function, "return_value"):
|
| 210 |
|
|
return_.expression = self.parse_expression()
|
| 211 |
|
|
self.tokens.expect(";")
|
| 212 |
|
|
return return_
|
| 213 |
|
|
|
| 214 |
|
|
def parse_assert(self):
|
| 215 |
|
|
assert_ = Assert()
|
| 216 |
|
|
assert_.allocator = self.allocator
|
| 217 |
|
|
self.tokens.expect("assert")
|
| 218 |
|
|
self.tokens.expect("(")
|
| 219 |
|
|
assert_.expression = self.parse_expression()
|
| 220 |
|
|
self.tokens.expect(")")
|
| 221 |
|
|
self.tokens.expect(";")
|
| 222 |
|
|
assert_.line = self.tokens.lineno
|
| 223 |
|
|
assert_.filename = self.tokens.filename
|
| 224 |
|
|
return assert_
|
| 225 |
|
|
|
| 226 |
|
|
def parse_report(self):
|
| 227 |
|
|
report_ = Report()
|
| 228 |
|
|
report_.allocator = self.allocator
|
| 229 |
|
|
self.tokens.expect("report")
|
| 230 |
|
|
self.tokens.expect("(")
|
| 231 |
|
|
report_.expression = self.parse_expression()
|
| 232 |
|
|
self.tokens.expect(")")
|
| 233 |
|
|
self.tokens.expect(";")
|
| 234 |
|
|
report_.line = self.tokens.lineno
|
| 235 |
|
|
report_.filename = self.tokens.filename
|
| 236 |
|
|
return report_
|
| 237 |
|
|
|
| 238 |
|
|
def parse_wait_clocks(self):
|
| 239 |
|
|
wait_clocks = WaitClocks()
|
| 240 |
|
|
wait_clocks.allocator = self.allocator
|
| 241 |
|
|
self.tokens.expect("wait_clocks")
|
| 242 |
|
|
self.tokens.expect("(")
|
| 243 |
|
|
wait_clocks.expression = self.parse_expression()
|
| 244 |
|
|
self.tokens.expect(")")
|
| 245 |
|
|
self.tokens.expect(";")
|
| 246 |
|
|
wait_clocks.line = self.tokens.lineno
|
| 247 |
|
|
return wait_clocks
|
| 248 |
|
|
|
| 249 |
|
|
def parse_statement(self):
|
| 250 |
4 |
jondawson |
if self.tokens.peek() in numeric_types + self.structs + storage_specifiers:
|
| 251 |
2 |
jondawson |
return self.parse_compound_declaration()
|
| 252 |
|
|
elif self.tokens.peek() == "struct":
|
| 253 |
|
|
return self.parse_struct_declaration()
|
| 254 |
|
|
elif self.tokens.peek() == "if":
|
| 255 |
|
|
return self.parse_if()
|
| 256 |
|
|
elif self.tokens.peek() == "while":
|
| 257 |
|
|
return self.parse_while()
|
| 258 |
|
|
elif self.tokens.peek() == "for":
|
| 259 |
|
|
return self.parse_for()
|
| 260 |
|
|
elif self.tokens.peek() == "return":
|
| 261 |
|
|
return self.parse_return()
|
| 262 |
|
|
elif self.tokens.peek() == "break":
|
| 263 |
|
|
return self.parse_break()
|
| 264 |
|
|
elif self.tokens.peek() == "continue":
|
| 265 |
|
|
return self.parse_continue()
|
| 266 |
|
|
elif self.tokens.peek() == "{":
|
| 267 |
|
|
return self.parse_block()
|
| 268 |
|
|
elif self.tokens.peek() == "assert":
|
| 269 |
|
|
return self.parse_assert()
|
| 270 |
|
|
elif self.tokens.peek() == "report":
|
| 271 |
|
|
return self.parse_report()
|
| 272 |
|
|
elif self.tokens.peek() == "switch":
|
| 273 |
|
|
return self.parse_switch()
|
| 274 |
|
|
elif self.tokens.peek() == "case":
|
| 275 |
|
|
return self.parse_case()
|
| 276 |
|
|
elif self.tokens.peek() == "default":
|
| 277 |
|
|
return self.parse_default()
|
| 278 |
|
|
elif self.tokens.peek() == "wait_clocks":
|
| 279 |
|
|
return self.parse_wait_clocks()
|
| 280 |
|
|
else:
|
| 281 |
|
|
expression = self.parse_discard()
|
| 282 |
|
|
self.tokens.expect(";")
|
| 283 |
|
|
return expression
|
| 284 |
|
|
|
| 285 |
|
|
def parse_discard(self):
|
| 286 |
|
|
return DiscardExpression(self.parse_expression(), self.allocator)
|
| 287 |
|
|
|
| 288 |
|
|
def parse_assignment(self):
|
| 289 |
|
|
assignment_operators = [
|
| 290 |
4 |
jondawson |
"=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>="
|
| 291 |
2 |
jondawson |
]
|
| 292 |
|
|
lvalue = self.parse_ternary_expression()
|
| 293 |
|
|
if self.tokens.peek() in assignment_operators:
|
| 294 |
4 |
jondawson |
if lvalue.const():
|
| 295 |
|
|
|
| 296 |
2 |
jondawson |
self.tokens.error(
|
| 297 |
4 |
jondawson |
"left hand operand of assignment is not modifiable")
|
| 298 |
|
|
|
| 299 |
2 |
jondawson |
operator = self.tokens.get()
|
| 300 |
|
|
if operator == "=":
|
| 301 |
|
|
expression = self.parse_ternary_expression()
|
| 302 |
|
|
else:
|
| 303 |
4 |
jondawson |
|
| 304 |
|
|
expression = self.parse_ternary_expression()
|
| 305 |
|
|
left = lvalue
|
| 306 |
|
|
left, expression = self.coerce_types(left, expression)
|
| 307 |
|
|
expression = Binary(operator[:-1], left, expression)
|
| 308 |
|
|
|
| 309 |
|
|
if expression.type_() != lvalue.type_():
|
| 310 |
|
|
if expression.type_() == "int" and lvalue.type_() == "float":
|
| 311 |
|
|
expression = IntToFloat(expression)
|
| 312 |
|
|
elif expression.type_() == "float" and lvalue.type_() == "int":
|
| 313 |
|
|
expression = FloatToInt(expression)
|
| 314 |
|
|
else:
|
| 315 |
|
|
self.tokens.error(
|
| 316 |
|
|
"type mismatch in assignment expected: %s actual: %s"%(
|
| 317 |
|
|
lvalue.type_(),
|
| 318 |
|
|
expression.type_()))
|
| 319 |
|
|
|
| 320 |
2 |
jondawson |
return Assignment(lvalue, expression, self.allocator)
|
| 321 |
|
|
else:
|
| 322 |
|
|
return lvalue
|
| 323 |
|
|
|
| 324 |
|
|
def parse_if(self):
|
| 325 |
|
|
if_ = If()
|
| 326 |
|
|
if_.allocator = self.allocator
|
| 327 |
|
|
self.tokens.expect("if")
|
| 328 |
|
|
self.tokens.expect("(")
|
| 329 |
|
|
if_.expression = self.parse_expression()
|
| 330 |
4 |
jondawson |
if if_.expression.type_() not in ["unsigned", "int", "short", "long", "char"]:
|
| 331 |
2 |
jondawson |
self.tokens.error(
|
| 332 |
4 |
jondawson |
"if statement conditional must be an integer like expression")
|
| 333 |
2 |
jondawson |
self.tokens.expect(")")
|
| 334 |
|
|
if_.true_statement = self.parse_statement()
|
| 335 |
|
|
if self.tokens.peek() == "else":
|
| 336 |
|
|
self.tokens.expect("else")
|
| 337 |
|
|
if_.false_statement = self.parse_statement()
|
| 338 |
|
|
else:
|
| 339 |
|
|
if_.false_statement = None
|
| 340 |
|
|
return if_
|
| 341 |
|
|
|
| 342 |
|
|
def parse_switch(self):
|
| 343 |
|
|
switch = Switch()
|
| 344 |
|
|
switch.cases = {}
|
| 345 |
|
|
self.tokens.expect("switch")
|
| 346 |
|
|
self.tokens.expect("(")
|
| 347 |
|
|
expression = self.parse_expression()
|
| 348 |
4 |
jondawson |
if expression.type_() not in ["unsigned", "int", "short", "long", "char"]:
|
| 349 |
2 |
jondawson |
self.tokens.error(
|
| 350 |
4 |
jondawson |
"switch statement expression must be an integer like expression")
|
| 351 |
2 |
jondawson |
self.tokens.expect(")")
|
| 352 |
|
|
stored_loop = self.loop
|
| 353 |
|
|
self.loop = switch
|
| 354 |
|
|
statement = self.parse_statement()
|
| 355 |
|
|
self.loop = stored_loop
|
| 356 |
|
|
switch.expression = expression
|
| 357 |
|
|
switch.allocator = self.allocator
|
| 358 |
|
|
switch.statement = statement
|
| 359 |
|
|
return switch
|
| 360 |
|
|
|
| 361 |
|
|
def parse_case(self):
|
| 362 |
|
|
self.tokens.expect("case")
|
| 363 |
|
|
expression = self.parse_expression()
|
| 364 |
4 |
jondawson |
if expression.type_() not in ["int"]:
|
| 365 |
2 |
jondawson |
self.tokens.error(
|
| 366 |
4 |
jondawson |
"case expression must be an integer like expression")
|
| 367 |
2 |
jondawson |
self.tokens.expect(":")
|
| 368 |
|
|
try:
|
| 369 |
4 |
jondawson |
expression = expression.value()
|
| 370 |
2 |
jondawson |
case = Case()
|
| 371 |
4 |
jondawson |
self.loop.cases[expression] = case
|
| 372 |
2 |
jondawson |
except NotConstant:
|
| 373 |
|
|
self.tokens.error("case expression must be constant")
|
| 374 |
|
|
except AttributeError:
|
| 375 |
|
|
self.tokens.error(
|
| 376 |
4 |
jondawson |
"case statements may only be use inside a switch statment")
|
| 377 |
2 |
jondawson |
return case
|
| 378 |
|
|
|
| 379 |
|
|
def parse_default(self):
|
| 380 |
|
|
self.tokens.expect("default")
|
| 381 |
|
|
self.tokens.expect(":")
|
| 382 |
|
|
default = Default()
|
| 383 |
|
|
if not hasattr(self.loop, "cases"):
|
| 384 |
|
|
self.tokens.error(
|
| 385 |
4 |
jondawson |
"default statements may only be used inside a switch statment")
|
| 386 |
2 |
jondawson |
if hasattr(self.loop, "default"):
|
| 387 |
|
|
self.tokens.error(
|
| 388 |
4 |
jondawson |
"A switch statement may only have one default statement")
|
| 389 |
2 |
jondawson |
self.loop.default=default
|
| 390 |
|
|
return default
|
| 391 |
|
|
|
| 392 |
|
|
def parse_while(self):
|
| 393 |
|
|
loop = Loop()
|
| 394 |
|
|
self.tokens.expect("while")
|
| 395 |
|
|
self.tokens.expect("(")
|
| 396 |
|
|
expression = self.parse_expression()
|
| 397 |
|
|
self.tokens.expect(")")
|
| 398 |
|
|
stored_loop = self.loop
|
| 399 |
|
|
self.loop = loop
|
| 400 |
|
|
statement = self.parse_statement()
|
| 401 |
|
|
self.loop = stored_loop
|
| 402 |
|
|
|
| 403 |
|
|
if_ = If()
|
| 404 |
|
|
loop.statement = if_
|
| 405 |
|
|
break_ = Break()
|
| 406 |
|
|
break_.loop = loop
|
| 407 |
|
|
if_.allocator = self.allocator
|
| 408 |
4 |
jondawson |
if expression.type_() not in ["int"]:
|
| 409 |
2 |
jondawson |
self.tokens.error(
|
| 410 |
4 |
jondawson |
"while statement conditional must be an integer like expression")
|
| 411 |
2 |
jondawson |
if_.expression = expression
|
| 412 |
|
|
if_.false_statement = break_
|
| 413 |
|
|
if_.true_statement = statement
|
| 414 |
|
|
|
| 415 |
|
|
return loop
|
| 416 |
|
|
|
| 417 |
|
|
def parse_for(self):
|
| 418 |
|
|
for_ = For()
|
| 419 |
|
|
for_.allocator = self.allocator
|
| 420 |
|
|
self.tokens.expect("for")
|
| 421 |
|
|
self.tokens.expect("(")
|
| 422 |
|
|
if self.tokens.peek() != ";":
|
| 423 |
|
|
for_.statement1 = self.parse_discard()
|
| 424 |
|
|
self.tokens.expect(";")
|
| 425 |
|
|
if self.tokens.peek() != ";":
|
| 426 |
|
|
for_.expression = self.parse_expression()
|
| 427 |
4 |
jondawson |
if for_.expression.type_() not in [
|
| 428 |
|
|
"unsigned",
|
| 429 |
|
|
"int",
|
| 430 |
|
|
"short",
|
| 431 |
|
|
"long",
|
| 432 |
|
|
"char"]:
|
| 433 |
|
|
|
| 434 |
2 |
jondawson |
self.tokens.error(
|
| 435 |
4 |
jondawson |
"For statement conditional must be an integer like expression")
|
| 436 |
|
|
|
| 437 |
2 |
jondawson |
self.tokens.expect(";")
|
| 438 |
|
|
if self.tokens.peek() != ")":
|
| 439 |
|
|
for_.statement2 = self.parse_discard()
|
| 440 |
|
|
self.tokens.expect(")")
|
| 441 |
|
|
stored_loop = self.loop
|
| 442 |
|
|
self.loop = for_
|
| 443 |
|
|
for_.statement3 = self.parse_statement()
|
| 444 |
|
|
self.loop = stored_loop
|
| 445 |
|
|
return for_
|
| 446 |
|
|
|
| 447 |
|
|
def parse_block(self):
|
| 448 |
|
|
block = Block()
|
| 449 |
4 |
jondawson |
stored_scope = copy(self.scope)
|
| 450 |
2 |
jondawson |
self.tokens.expect("{")
|
| 451 |
|
|
block.statements = []
|
| 452 |
|
|
while self.tokens.peek() != "}":
|
| 453 |
|
|
block.statements.append(self.parse_statement())
|
| 454 |
|
|
self.tokens.expect("}")
|
| 455 |
|
|
self.scope = stored_scope
|
| 456 |
|
|
return block
|
| 457 |
|
|
|
| 458 |
|
|
def parse_struct_body(self):
|
| 459 |
|
|
self.tokens.expect("{")
|
| 460 |
|
|
members = {}
|
| 461 |
|
|
while self.tokens.peek() != "}":
|
| 462 |
4 |
jondawson |
type_, size, signed, const = self.parse_type_specifier()
|
| 463 |
2 |
jondawson |
name = self.tokens.get()
|
| 464 |
4 |
jondawson |
|
| 465 |
|
|
members[name] = self.parse_declaration(
|
| 466 |
|
|
type_,
|
| 467 |
|
|
size,
|
| 468 |
|
|
signed,
|
| 469 |
|
|
const,
|
| 470 |
|
|
name)
|
| 471 |
|
|
|
| 472 |
2 |
jondawson |
self.tokens.expect(";")
|
| 473 |
|
|
self.tokens.expect("}")
|
| 474 |
|
|
return members
|
| 475 |
|
|
|
| 476 |
|
|
def parse_typedef_struct(self):
|
| 477 |
|
|
self.tokens.expect("typedef")
|
| 478 |
|
|
self.tokens.expect("struct")
|
| 479 |
|
|
declaration = StructDeclaration(self.parse_struct_body())
|
| 480 |
|
|
name = self.tokens.get()
|
| 481 |
|
|
self.tokens.expect(";")
|
| 482 |
|
|
self.scope[name] = declaration
|
| 483 |
|
|
self.structs.append(name)
|
| 484 |
|
|
|
| 485 |
|
|
def parse_define_struct(self):
|
| 486 |
|
|
self.tokens.expect("struct")
|
| 487 |
|
|
name = self.tokens.get()
|
| 488 |
|
|
declaration = StructDeclaration(self.parse_struct_body())
|
| 489 |
|
|
self.tokens.expect(";")
|
| 490 |
|
|
self.scope[name] = declaration
|
| 491 |
|
|
|
| 492 |
|
|
def parse_struct_declaration(self):
|
| 493 |
|
|
self.tokens.expect("struct")
|
| 494 |
|
|
struct_name = self.tokens.get()
|
| 495 |
|
|
name = self.tokens.get()
|
| 496 |
|
|
self.tokens.expect(";")
|
| 497 |
|
|
instance = self.scope[struct_name].instance()
|
| 498 |
|
|
self.scope[name] = instance
|
| 499 |
|
|
return instance
|
| 500 |
|
|
|
| 501 |
4 |
jondawson |
def parse_global_declaration(self, type_, size, signed, const, name):
|
| 502 |
2 |
jondawson |
instances = []
|
| 503 |
|
|
while True:
|
| 504 |
4 |
jondawson |
|
| 505 |
|
|
instance = self.parse_declaration(
|
| 506 |
|
|
type_,
|
| 507 |
|
|
size,
|
| 508 |
|
|
signed,
|
| 509 |
|
|
const,
|
| 510 |
|
|
name).instance()
|
| 511 |
|
|
|
| 512 |
2 |
jondawson |
self.scope[name] = instance
|
| 513 |
|
|
instances.append(instance)
|
| 514 |
|
|
if self.tokens.peek() == ",":
|
| 515 |
|
|
self.tokens.expect(",")
|
| 516 |
|
|
else:
|
| 517 |
|
|
break
|
| 518 |
|
|
name = self.tokens.get()
|
| 519 |
|
|
self.tokens.expect(";")
|
| 520 |
|
|
return CompoundDeclaration(instances)
|
| 521 |
|
|
|
| 522 |
|
|
def parse_compound_declaration(self):
|
| 523 |
4 |
jondawson |
type_, size, signed, const = self.parse_type_specifier()
|
| 524 |
2 |
jondawson |
instances = []
|
| 525 |
|
|
while True:
|
| 526 |
|
|
name = self.tokens.get()
|
| 527 |
4 |
jondawson |
|
| 528 |
|
|
instance = self.parse_declaration(
|
| 529 |
|
|
type_,
|
| 530 |
|
|
size,
|
| 531 |
|
|
signed,
|
| 532 |
|
|
const,
|
| 533 |
|
|
name).instance()
|
| 534 |
|
|
|
| 535 |
2 |
jondawson |
self.scope[name] = instance
|
| 536 |
|
|
instances.append(instance)
|
| 537 |
|
|
if self.tokens.peek() == ",":
|
| 538 |
|
|
self.tokens.expect(",")
|
| 539 |
|
|
else:
|
| 540 |
|
|
break
|
| 541 |
|
|
name = None
|
| 542 |
|
|
self.tokens.expect(";")
|
| 543 |
|
|
return CompoundDeclaration(instances)
|
| 544 |
|
|
|
| 545 |
4 |
jondawson |
def parse_declaration(self, type_, size, signed, const, name):
|
| 546 |
2 |
jondawson |
#struct declaration
|
| 547 |
|
|
if type_ in self.structs:
|
| 548 |
|
|
declaration = self.scope[type_]
|
| 549 |
4 |
jondawson |
elif type_ in ["int", "float"]:
|
| 550 |
|
|
#array declaration
|
| 551 |
2 |
jondawson |
if self.tokens.peek() == "[":
|
| 552 |
|
|
array_size = None
|
| 553 |
|
|
self.tokens.expect("[")
|
| 554 |
|
|
if self.tokens.peek() != "]":
|
| 555 |
4 |
jondawson |
size_expression = self.parse_ternary_expression()
|
| 556 |
|
|
if size_expression.type_() != "int":
|
| 557 |
|
|
self.tokens.error("Array size must be an integer like expression")
|
| 558 |
|
|
try:
|
| 559 |
|
|
array_size = size_expression.value()
|
| 560 |
|
|
except NotConstant:
|
| 561 |
|
|
self.tokens.error("Array size must be constant")
|
| 562 |
|
|
|
| 563 |
2 |
jondawson |
self.tokens.expect("]")
|
| 564 |
|
|
initializer = None
|
| 565 |
|
|
if self.tokens.peek() == "=":
|
| 566 |
|
|
self.tokens.expect("=")
|
| 567 |
|
|
initializer = self.tokens.get()
|
| 568 |
|
|
initializer = [ord(i) for i in initializer.strip('"').decode("string_escape")] + [0]
|
| 569 |
|
|
array_size = len(initializer)
|
| 570 |
|
|
if array_size is None:
|
| 571 |
4 |
jondawson |
|
| 572 |
|
|
self.tokens.error(
|
| 573 |
|
|
"array size must be specified if not initialized")
|
| 574 |
|
|
|
| 575 |
2 |
jondawson |
array_type=type_+"[]"
|
| 576 |
|
|
initialize_memory = self.initialize_memory
|
| 577 |
4 |
jondawson |
declaration = ArrayDeclaration(
|
| 578 |
|
|
self.allocator,
|
| 579 |
|
|
array_size,
|
| 580 |
|
|
array_type,
|
| 581 |
|
|
type_,
|
| 582 |
|
|
size,
|
| 583 |
|
|
signed,
|
| 584 |
|
|
initializer,
|
| 585 |
|
|
self.initialize_memory)
|
| 586 |
2 |
jondawson |
|
| 587 |
4 |
jondawson |
#simple variable declaration
|
| 588 |
2 |
jondawson |
else:
|
| 589 |
|
|
if self.tokens.peek() == "=":
|
| 590 |
|
|
self.tokens.expect("=")
|
| 591 |
|
|
initializer = self.parse_ternary_expression()
|
| 592 |
|
|
else:
|
| 593 |
4 |
jondawson |
initializer = Constant(0, type_, size, signed)
|
| 594 |
|
|
|
| 595 |
|
|
if type_ != initializer.type_():
|
| 596 |
|
|
|
| 597 |
|
|
if type_ == "int" and initializer.type_() == "float":
|
| 598 |
|
|
initializer = FloatToInt(initializer)
|
| 599 |
|
|
elif type_ == "float" and initializer.type_() == "int":
|
| 600 |
|
|
initializer = IntToFloat(initializer)
|
| 601 |
|
|
else:
|
| 602 |
|
|
self.tokens.error(
|
| 603 |
|
|
"type mismatch in intializer expected: %s actual: %s"%(
|
| 604 |
|
|
type_,
|
| 605 |
|
|
intitializer.type_()))
|
| 606 |
2 |
jondawson |
declaration = VariableDeclaration(
|
| 607 |
4 |
jondawson |
self.allocator,
|
| 608 |
|
|
initializer,
|
| 609 |
2 |
jondawson |
name,
|
| 610 |
|
|
type_,
|
| 611 |
|
|
size,
|
| 612 |
4 |
jondawson |
signed,
|
| 613 |
|
|
const
|
| 614 |
2 |
jondawson |
)
|
| 615 |
|
|
|
| 616 |
|
|
return declaration
|
| 617 |
|
|
|
| 618 |
|
|
def parse_expression(self):
|
| 619 |
|
|
expression = self.parse_assignment()
|
| 620 |
|
|
return expression
|
| 621 |
|
|
|
| 622 |
|
|
def parse_ternary_expression(self):
|
| 623 |
|
|
expression = constant_fold(self.parse_or_expression())
|
| 624 |
|
|
while self.tokens.peek() in ["?"]:
|
| 625 |
|
|
self.tokens.expect("?")
|
| 626 |
|
|
true_expression = constant_fold(self.parse_or_expression())
|
| 627 |
|
|
self.tokens.expect(":")
|
| 628 |
|
|
false_expression = constant_fold(self.parse_or_expression())
|
| 629 |
|
|
expression = OR(AND(expression, true_expression), false_expression)
|
| 630 |
|
|
return expression
|
| 631 |
|
|
|
| 632 |
|
|
def parse_or_expression(self):
|
| 633 |
|
|
expression = self.parse_and_expression()
|
| 634 |
|
|
while self.tokens.peek() in ["||"]:
|
| 635 |
|
|
self.tokens.expect("||")
|
| 636 |
|
|
expression = OR(expression, self.parse_and_expression())
|
| 637 |
|
|
return expression
|
| 638 |
|
|
|
| 639 |
|
|
def parse_and_expression(self):
|
| 640 |
|
|
expression = self.parse_binary_expression(["|"])
|
| 641 |
|
|
while self.tokens.peek() in ["&&"]:
|
| 642 |
|
|
self.tokens.expect("&&")
|
| 643 |
|
|
expression = AND(expression, self.parse_binary_expression(["|"]))
|
| 644 |
|
|
return expression
|
| 645 |
|
|
|
| 646 |
4 |
jondawson |
def substitute_function(self, binary_expression):
|
| 647 |
|
|
|
| 648 |
|
|
"""
|
| 649 |
|
|
For some operations are more easily implemented in sofftware.
|
| 650 |
|
|
This function substitutes a call to the builtin library function.
|
| 651 |
|
|
"""
|
| 652 |
|
|
|
| 653 |
|
|
functions = {
|
| 654 |
|
|
"False,int,int,4,/" : "long_unsigned_divide_xxxx",
|
| 655 |
|
|
"True,int,int,4,/" : "long_divide_xxxx",
|
| 656 |
|
|
"False,int,int,2,/" : "unsigned_divide_xxxx",
|
| 657 |
|
|
"True,int,int,2,/" : "divide_xxxx",
|
| 658 |
|
|
"False,int,int,4,%" : "long_unsigned_modulo_xxxx",
|
| 659 |
|
|
"True,int,int,4,%" : "long_modulo_xxxx",
|
| 660 |
|
|
"False,int,int,2,%" : "unsigned_modulo_xxxx",
|
| 661 |
|
|
"True,int,int,2,%" : "modulo_xxxx",
|
| 662 |
|
|
"True,float,float,4,==" : "float_equal_xxxx",
|
| 663 |
|
|
"True,float,float,4,!=" : "float_ne_xxxx",
|
| 664 |
|
|
"True,float,float,4,<" : "float_lt_xxxx",
|
| 665 |
|
|
"True,float,float,4,>" : "float_gt_xxxx",
|
| 666 |
|
|
"True,float,float,4,<=" : "float_le_xxxx",
|
| 667 |
|
|
"True,float,float,4,>=" : "float_ge_xxxx",
|
| 668 |
|
|
}
|
| 669 |
|
|
|
| 670 |
|
|
#select a function that matches the template.
|
| 671 |
|
|
signature = ",".join([
|
| 672 |
|
|
str(binary_expression.signed()),
|
| 673 |
|
|
binary_expression.left.type_(),
|
| 674 |
|
|
binary_expression.right.type_(),
|
| 675 |
|
|
str(binary_expression.size()),
|
| 676 |
|
|
binary_expression.operator])
|
| 677 |
|
|
|
| 678 |
2 |
jondawson |
#Some things can't be implemented in verilog, substitute them with a function
|
| 679 |
4 |
jondawson |
if signature in functions:
|
| 680 |
|
|
function = self.scope[functions[signature]]
|
| 681 |
|
|
function_call = FunctionCall(function)
|
| 682 |
|
|
function_call.arguments = [binary_expression.left, binary_expression.right]
|
| 683 |
2 |
jondawson |
return function_call
|
| 684 |
|
|
else:
|
| 685 |
4 |
jondawson |
return binary_expression
|
| 686 |
2 |
jondawson |
|
| 687 |
4 |
jondawson |
def coerce_types(self, left, right):
|
| 688 |
|
|
|
| 689 |
|
|
"""
|
| 690 |
|
|
Convert numeric types in expressions.
|
| 691 |
|
|
"""
|
| 692 |
|
|
|
| 693 |
|
|
if left.type_() != right.type_():
|
| 694 |
|
|
if left.type_() == "float" and right.type_() == "int":
|
| 695 |
|
|
return left, IntToFloat(right)
|
| 696 |
|
|
elif left.type_() == "int" and right.type_() == "float":
|
| 697 |
|
|
return IntToFloat(left), right
|
| 698 |
|
|
else:
|
| 699 |
|
|
self.tokens.error("Incompatible types : %s %s"%(
|
| 700 |
|
|
left.type_(),
|
| 701 |
|
|
right.type_()))
|
| 702 |
|
|
|
| 703 |
|
|
return left, right
|
| 704 |
|
|
|
| 705 |
2 |
jondawson |
def parse_binary_expression(self, operators):
|
| 706 |
|
|
operator_precedence = {
|
| 707 |
|
|
"|": ["^"],
|
| 708 |
|
|
"^": ["&"],
|
| 709 |
|
|
"&": ["==", "!="],
|
| 710 |
|
|
"==": ["<", ">", "<=", ">="],
|
| 711 |
|
|
"<": ["<<", ">>"],
|
| 712 |
|
|
"<<": ["+", "-"],
|
| 713 |
|
|
"+": ["*", "/", "%"],
|
| 714 |
|
|
}
|
| 715 |
|
|
if operators[0] not in operator_precedence:
|
| 716 |
4 |
jondawson |
left = self.parse_unary_expression()
|
| 717 |
2 |
jondawson |
while self.tokens.peek() in operators:
|
| 718 |
|
|
operator = self.tokens.get()
|
| 719 |
|
|
right = self.parse_unary_expression()
|
| 720 |
4 |
jondawson |
left, right = self.coerce_types(left, right)
|
| 721 |
|
|
left = Binary(operator, left, right)
|
| 722 |
|
|
left = self.substitute_function(left)
|
| 723 |
|
|
return left
|
| 724 |
2 |
jondawson |
else:
|
| 725 |
|
|
next_operators = operator_precedence[operators[0]]
|
| 726 |
4 |
jondawson |
left = self.parse_binary_expression(next_operators)
|
| 727 |
2 |
jondawson |
while self.tokens.peek() in operators:
|
| 728 |
4 |
jondawson |
operator = self.tokens.get()
|
| 729 |
|
|
right = self.parse_binary_expression(next_operators)
|
| 730 |
|
|
left, right = self.coerce_types(left, right)
|
| 731 |
|
|
left = Binary(operator, left, right)
|
| 732 |
|
|
left = self.substitute_function(left)
|
| 733 |
|
|
return left
|
| 734 |
2 |
jondawson |
|
| 735 |
|
|
def parse_unary_expression(self):
|
| 736 |
|
|
if self.tokens.peek() == "!":
|
| 737 |
|
|
operator = self.tokens.get()
|
| 738 |
|
|
expression = self.parse_postfix_expression()
|
| 739 |
4 |
jondawson |
return Binary("==", expression, Constant(0))
|
| 740 |
2 |
jondawson |
elif self.tokens.peek() == "-":
|
| 741 |
|
|
operator = self.tokens.get()
|
| 742 |
|
|
expression = self.parse_postfix_expression()
|
| 743 |
4 |
jondawson |
return Binary("-", Constant(0,
|
| 744 |
|
|
expression.type_(),
|
| 745 |
|
|
expression.size(),
|
| 746 |
|
|
expression.signed()),
|
| 747 |
|
|
expression)
|
| 748 |
2 |
jondawson |
elif self.tokens.peek() == "~":
|
| 749 |
|
|
operator = self.tokens.get()
|
| 750 |
|
|
expression = self.parse_postfix_expression()
|
| 751 |
4 |
jondawson |
return Unary("~", expression)
|
| 752 |
2 |
jondawson |
elif self.tokens.peek() == "sizeof":
|
| 753 |
|
|
operator = self.tokens.get()
|
| 754 |
|
|
expression = self.parse_unary_expression()
|
| 755 |
|
|
return SizeOf(expression)
|
| 756 |
|
|
else:
|
| 757 |
|
|
return self.parse_postfix_expression()
|
| 758 |
|
|
|
| 759 |
|
|
def parse_postfix_expression(self):
|
| 760 |
|
|
expression = self.parse_paren_expression()
|
| 761 |
|
|
while self.tokens.peek() in ["++", "--"]:
|
| 762 |
|
|
operator = self.tokens.get()
|
| 763 |
|
|
expression = PostIncrement(
|
| 764 |
|
|
operator[:-1],
|
| 765 |
4 |
jondawson |
expression,
|
| 766 |
2 |
jondawson |
self.allocator
|
| 767 |
|
|
)
|
| 768 |
|
|
return expression
|
| 769 |
|
|
|
| 770 |
|
|
def parse_paren_expression(self):
|
| 771 |
|
|
if self.tokens.peek() == "(":
|
| 772 |
|
|
self.tokens.expect("(")
|
| 773 |
|
|
expression = self.parse_expression()
|
| 774 |
|
|
self.tokens.expect(")")
|
| 775 |
|
|
else:
|
| 776 |
|
|
expression = self.parse_number_or_variable()
|
| 777 |
|
|
return expression
|
| 778 |
|
|
|
| 779 |
|
|
def parse_number_or_variable(self):
|
| 780 |
|
|
if self.tokens.peek()[0].isalpha():
|
| 781 |
|
|
name = self.tokens.get()
|
| 782 |
|
|
if self.tokens.peek() == "(":
|
| 783 |
|
|
return self.parse_function_call(name)
|
| 784 |
|
|
else:
|
| 785 |
|
|
return self.parse_variable(name)
|
| 786 |
|
|
else:
|
| 787 |
|
|
return self.parse_number()
|
| 788 |
|
|
|
| 789 |
|
|
def parse_file_read(self):
|
| 790 |
|
|
self.tokens.expect("(")
|
| 791 |
|
|
file_name = self.tokens.get()
|
| 792 |
|
|
file_name = file_name.strip('"').decode("string_escape")
|
| 793 |
|
|
self.tokens.expect(")")
|
| 794 |
|
|
return FileRead(file_name)
|
| 795 |
|
|
|
| 796 |
|
|
def parse_file_write(self):
|
| 797 |
|
|
self.tokens.expect("(")
|
| 798 |
|
|
expression = self.parse_expression()
|
| 799 |
|
|
self.tokens.expect(",")
|
| 800 |
|
|
file_name = self.tokens.get()
|
| 801 |
|
|
file_name = file_name.strip('"').decode("string_escape")
|
| 802 |
|
|
self.tokens.expect(")")
|
| 803 |
|
|
return FileWrite(file_name, expression)
|
| 804 |
|
|
|
| 805 |
|
|
def parse_input(self, name):
|
| 806 |
|
|
input_name = name.replace("input_", "")
|
| 807 |
|
|
self.tokens.expect("(")
|
| 808 |
|
|
self.tokens.expect(")")
|
| 809 |
|
|
return Input(input_name)
|
| 810 |
|
|
|
| 811 |
|
|
def parse_ready(self, name):
|
| 812 |
|
|
input_name = name.replace("ready_", "")
|
| 813 |
|
|
self.tokens.expect("(")
|
| 814 |
|
|
self.tokens.expect(")")
|
| 815 |
|
|
return Ready(input_name)
|
| 816 |
|
|
|
| 817 |
|
|
def parse_output(self, name):
|
| 818 |
|
|
output_name = name.replace("output_", "")
|
| 819 |
|
|
self.tokens.expect("(")
|
| 820 |
|
|
expression = self.parse_expression()
|
| 821 |
|
|
self.tokens.expect(")")
|
| 822 |
|
|
return Output(output_name, expression)
|
| 823 |
|
|
|
| 824 |
|
|
def parse_function_call(self, name):
|
| 825 |
|
|
if name.startswith("input_"):
|
| 826 |
|
|
return self.parse_input(name)
|
| 827 |
|
|
if name.startswith("ready_"):
|
| 828 |
|
|
return self.parse_ready(name)
|
| 829 |
|
|
if name.startswith("output_"):
|
| 830 |
|
|
return self.parse_output(name)
|
| 831 |
|
|
if name == "file_read":
|
| 832 |
|
|
return self.parse_file_read()
|
| 833 |
|
|
if name == "file_write":
|
| 834 |
|
|
return self.parse_file_write()
|
| 835 |
4 |
jondawson |
if name not in self.scope:
|
| 836 |
|
|
self.tokens.error("Unknown function: %s"%name)
|
| 837 |
|
|
function = self.scope[name]
|
| 838 |
|
|
function_call = FunctionCall(function)
|
| 839 |
2 |
jondawson |
function_call.arguments = []
|
| 840 |
|
|
self.tokens.expect("(")
|
| 841 |
|
|
while self.tokens.peek() != ")":
|
| 842 |
|
|
function_call.arguments.append(self.parse_expression())
|
| 843 |
|
|
if self.tokens.peek() == ",":
|
| 844 |
|
|
self.tokens.expect(",")
|
| 845 |
|
|
else:
|
| 846 |
|
|
break
|
| 847 |
|
|
self.tokens.expect(")")
|
| 848 |
|
|
|
| 849 |
|
|
|
| 850 |
|
|
required_arguments = len(function_call.function.arguments)
|
| 851 |
|
|
actual_arguments = len(function_call.arguments)
|
| 852 |
|
|
if required_arguments != actual_arguments:
|
| 853 |
|
|
self.tokens.error("Function %s takes %s arguments %s given."%(
|
| 854 |
|
|
name,
|
| 855 |
|
|
len(function_call.function.arguments),
|
| 856 |
4 |
jondawson |
len(function_call.arguments)))
|
| 857 |
2 |
jondawson |
required_arguments = function_call.function.arguments
|
| 858 |
|
|
actual_arguments = function_call.arguments
|
| 859 |
4 |
jondawson |
corrected_arguments = []
|
| 860 |
2 |
jondawson |
for required, actual in zip(required_arguments, actual_arguments):
|
| 861 |
4 |
jondawson |
if not compatible(required, actual):
|
| 862 |
|
|
if actual.type_() == "int" and required.type_() == "float":
|
| 863 |
|
|
actual = IntToFloat(actual)
|
| 864 |
|
|
elif actual.type_() == "float" and required.type_() == "int":
|
| 865 |
|
|
actual = FloatToInt(actual)
|
| 866 |
|
|
else:
|
| 867 |
|
|
self.tokens.error(
|
| 868 |
|
|
"type mismatch in assignment expected: %s actual: %s"%(
|
| 869 |
|
|
required.type_(),
|
| 870 |
|
|
actual.type_()))
|
| 871 |
|
|
corrected_arguments.append(actual)
|
| 872 |
|
|
function_call.arguments = corrected_arguments
|
| 873 |
2 |
jondawson |
|
| 874 |
|
|
return function_call
|
| 875 |
|
|
|
| 876 |
|
|
def parse_number(self):
|
| 877 |
|
|
token = self.tokens.get()
|
| 878 |
4 |
jondawson |
type_ = "int"
|
| 879 |
2 |
jondawson |
size = 2
|
| 880 |
|
|
signed = True
|
| 881 |
|
|
if token.startswith("'"):
|
| 882 |
|
|
try:
|
| 883 |
|
|
token = eval(token)
|
| 884 |
|
|
value = ord(token)
|
| 885 |
|
|
except SyntaxError:
|
| 886 |
|
|
self.tokens.error("%s is not a character literal"%token)
|
| 887 |
|
|
elif token.startswith('"'):
|
| 888 |
|
|
try:
|
| 889 |
|
|
initializer = [ord(i) for i in token.strip('"').decode("string_escape")] + [0]
|
| 890 |
|
|
size = len(initializer)
|
| 891 |
|
|
initialize_memory = self.initialize_memory
|
| 892 |
|
|
declaration = ArrayDeclaration(
|
| 893 |
4 |
jondawson |
self.allocator,
|
| 894 |
|
|
size,
|
| 895 |
|
|
"int[]",
|
| 896 |
|
|
"int",
|
| 897 |
|
|
2,
|
| 898 |
|
|
False,
|
| 899 |
|
|
initializer,
|
| 900 |
2 |
jondawson |
self.initialize_memory)
|
| 901 |
4 |
jondawson |
return ConstArray(declaration.instance())
|
| 902 |
2 |
jondawson |
except SyntaxError:
|
| 903 |
|
|
self.tokens.error("%s is not a character literal"%token)
|
| 904 |
4 |
jondawson |
elif "." in token:
|
| 905 |
|
|
#float literal
|
| 906 |
|
|
try:
|
| 907 |
|
|
type_ = "float"
|
| 908 |
|
|
signed = True
|
| 909 |
|
|
size = 4
|
| 910 |
|
|
token = token.upper().replace("F", "")
|
| 911 |
|
|
token = token.upper().replace("L", "")
|
| 912 |
|
|
value = float(eval(token))
|
| 913 |
|
|
|
| 914 |
|
|
try:
|
| 915 |
|
|
byte_value = struct.pack(">f", value)
|
| 916 |
|
|
except OverflowError:
|
| 917 |
|
|
self.tokens.error("value too large")
|
| 918 |
|
|
|
| 919 |
|
|
except SyntaxError:
|
| 920 |
|
|
self.tokens.error("%s is not a floating point literal"%token)
|
| 921 |
2 |
jondawson |
else:
|
| 922 |
4 |
jondawson |
#integer literal
|
| 923 |
2 |
jondawson |
try:
|
| 924 |
|
|
if "U" in token.upper():
|
| 925 |
|
|
signed = False
|
| 926 |
|
|
if "L" in token.upper():
|
| 927 |
|
|
size = 4
|
| 928 |
|
|
token = token.upper().replace("U", "")
|
| 929 |
|
|
value = int(eval(token))
|
| 930 |
|
|
|
| 931 |
|
|
if signed:
|
| 932 |
|
|
if value > 2**((size * 8)-1) - 1:
|
| 933 |
|
|
self.tokens.error("value too large")
|
| 934 |
|
|
if value < -(2**((size * 8)-1)):
|
| 935 |
|
|
self.tokens.error("value too small")
|
| 936 |
|
|
else:
|
| 937 |
|
|
if value > 2**(size * 8) - 1:
|
| 938 |
|
|
self.tokens.error("value too large")
|
| 939 |
|
|
if value < 0:
|
| 940 |
|
|
self.tokens.error("value too small")
|
| 941 |
|
|
|
| 942 |
|
|
except SyntaxError:
|
| 943 |
|
|
self.tokens.error("%s is not an integer literal"%token)
|
| 944 |
|
|
|
| 945 |
4 |
jondawson |
return Constant(value, type_, size, signed)
|
| 946 |
|
|
|
| 947 |
2 |
jondawson |
def parse_variable(self, name):
|
| 948 |
|
|
if name not in self.scope:
|
| 949 |
|
|
self.tokens.error("Unknown variable: %s"%name)
|
| 950 |
|
|
instance = self.scope[name]
|
| 951 |
|
|
return self.parse_variable_array_struct(instance)
|
| 952 |
4 |
jondawson |
|
| 953 |
2 |
jondawson |
def parse_variable_array_struct(self, instance):
|
| 954 |
4 |
jondawson |
if instance.type_() in numeric_types:
|
| 955 |
|
|
|
| 956 |
|
|
if not hasattr(instance, "reference"):
|
| 957 |
|
|
|
| 958 |
|
|
self.tokens.error(
|
| 959 |
|
|
"Not an expression")
|
| 960 |
|
|
|
| 961 |
|
|
return Variable(instance)
|
| 962 |
|
|
elif instance.type_().endswith("[]"):
|
| 963 |
2 |
jondawson |
if self.tokens.peek() == "[":
|
| 964 |
|
|
self.tokens.expect("[")
|
| 965 |
|
|
index_expression = self.parse_expression()
|
| 966 |
|
|
self.tokens.expect("]")
|
| 967 |
4 |
jondawson |
if index_expression.type_() not in ["int"]:
|
| 968 |
|
|
|
| 969 |
2 |
jondawson |
self.tokens.error(
|
| 970 |
4 |
jondawson |
"Array indices must be an integer like expression")
|
| 971 |
|
|
|
| 972 |
|
|
return ArrayIndex(instance, index_expression)
|
| 973 |
2 |
jondawson |
else:
|
| 974 |
4 |
jondawson |
return Array(instance)
|
| 975 |
|
|
elif instance.type_().startswith("struct"):
|
| 976 |
|
|
if self.tokens.peek() == ".":
|
| 977 |
|
|
self.tokens.expect(".")
|
| 978 |
|
|
member = self.tokens.get()
|
| 979 |
|
|
instance = instance.members[member]
|
| 980 |
|
|
return self.parse_variable_array_struct(instance)
|
| 981 |
|
|
else:
|
| 982 |
|
|
return Struct(instance)
|
| 983 |
2 |
jondawson |
|
| 984 |
|
|
def compatible(left, right):
|
| 985 |
4 |
jondawson |
return left.type_() == right.type_()
|