|
@@ 330-368 (lines=39) @@
|
| 327 |
|
# TODO: Move Frame to separate module to fix the cyclic import. |
| 328 |
|
from evaluator import Frame |
| 329 |
|
|
| 330 |
|
if frame.expression_index == 0: |
| 331 |
|
# We don't evaluate the if symbol. |
| 332 |
|
frame.expression_index += 1 |
| 333 |
|
return None |
| 334 |
|
|
| 335 |
|
elif frame.expression_index == 1: |
| 336 |
|
# Evaluate the condition. |
| 337 |
|
stack.push(Frame(condition, environment)) |
| 338 |
|
|
| 339 |
|
frame.expression_index += 1 |
| 340 |
|
return None |
| 341 |
|
|
| 342 |
|
elif frame.expression_index == 2: |
| 343 |
|
# We've evaluated the condition, so either evaluate 'then' |
| 344 |
|
# or 'otherwise' depending on the return value. |
| 345 |
|
evalled_condition = frame.evalled[-1] |
| 346 |
|
|
| 347 |
|
if evalled_condition == TRUE: |
| 348 |
|
stack.push(Frame(then, environment)) |
| 349 |
|
|
| 350 |
|
frame.expression_index += 1 |
| 351 |
|
return None |
| 352 |
|
|
| 353 |
|
elif evalled_condition == FALSE: |
| 354 |
|
stack.push(Frame(otherwise, environment)) |
| 355 |
|
|
| 356 |
|
frame.expression_index += 2 |
| 357 |
|
return None |
| 358 |
|
|
| 359 |
|
else: |
| 360 |
|
return TrifleExceptionInstance( |
| 361 |
|
wrong_type, |
| 362 |
|
u"The first argument to if must be a boolean, but got: %s" % |
| 363 |
|
evalled_condition.repr()) |
| 364 |
|
|
| 365 |
|
else: |
| 366 |
|
# We've evaluated the condition and either 'then' or |
| 367 |
|
# 'otherwise', so pop this frame and return. |
| 368 |
|
return frame.evalled[-1] |
| 369 |
|
|
| 370 |
|
|
| 371 |
|
class While(Special): |
|
@@ 382-415 (lines=34) @@
|
| 379 |
|
|
| 380 |
|
from evaluator import Frame |
| 381 |
|
|
| 382 |
|
if frame.expression_index == 0: |
| 383 |
|
# We don't evaluate the while symbol. |
| 384 |
|
frame.expression_index += 1 |
| 385 |
|
return None |
| 386 |
|
|
| 387 |
|
elif frame.expression_index == 1: |
| 388 |
|
# Evaluate the condition. |
| 389 |
|
stack.push(Frame(condition, env)) |
| 390 |
|
|
| 391 |
|
frame.expression_index += 1 |
| 392 |
|
return None |
| 393 |
|
|
| 394 |
|
elif frame.expression_index == 2: |
| 395 |
|
# We've evaluated the condition, so either evaluate the body, or return. |
| 396 |
|
evalled_condition = frame.evalled[-1] |
| 397 |
|
|
| 398 |
|
if evalled_condition == TRUE: |
| 399 |
|
stack.push(Frame(body, env, as_block=True)) |
| 400 |
|
|
| 401 |
|
# Once we've evaluated the body, we should evaluate |
| 402 |
|
# the condition again. |
| 403 |
|
frame.expression_index = 1 |
| 404 |
|
|
| 405 |
|
return None |
| 406 |
|
|
| 407 |
|
elif evalled_condition == FALSE: |
| 408 |
|
# while loops always return #null when done. |
| 409 |
|
return NULL |
| 410 |
|
|
| 411 |
|
else: |
| 412 |
|
return TrifleExceptionInstance( |
| 413 |
|
wrong_type, |
| 414 |
|
u"The first argument to while must be a boolean, but got: %s" % |
| 415 |
|
evalled_condition.repr()) |
| 416 |
|
|
| 417 |
|
|
| 418 |
|
# todo: implement in prelude in terms of stdin and stdout |