|
332 | 332 | ((is-top-scope-class-divider? state) '()) |
333 | 333 | (else (cons (get-top-scope state) (extract-new-class-instance-state-sub (get-tail-scope state))))))) |
334 | 334 |
|
| 335 | +; Updates a class instance with a new instance state |
335 | 336 | (define update-class-instance |
336 | 337 | (lambda (instancename new-instance-state state) |
337 | | - (G-push-state->state |
338 | | - instancename |
339 | | - (list (car (get-value-from-pair (G-value-lookup->value_state instancename state empty-cfuncs))) new-instance-state) |
340 | | - state))) |
| 338 | + (G-push-state->state instancename |
| 339 | + (list (get-instance-value-front (get-value-from-pair (G-value-lookup->value_state instancename state empty-cfuncs))) |
| 340 | + new-instance-state) |
| 341 | + state))) |
341 | 342 |
|
| 343 | +(define get-instance-value-front car) |
| 344 | + |
| 345 | +; Pops a state to the class level |
342 | 346 | (define G-pop-to-class-level->state |
343 | 347 | (lambda (state) |
344 | | - (list (car (reverse state))))) |
| 348 | + (list (get-reversedstate-head (reverse state))))) |
| 349 | + |
| 350 | +(define get-reversedstate-head car) |
345 | 351 |
|
346 | 352 |
|
347 | 353 | ; Pushes a stack divider to a state |
|
350 | 356 | (cons `((.cf) (,classname)) state))) |
351 | 357 |
|
352 | 358 |
|
| 359 | +; Gets a valid state for a 'this' keyword call |
353 | 360 | (define get-valid-this-call-state |
354 | 361 | (lambda (state) |
355 | 362 | (cond |
|
383 | 390 | (cond |
384 | 391 | ; If the if condition is true, evaluate the statements inside of it. |
385 | 392 | ((get-value-from-pair eval-ifcond) |
386 | | - |
387 | | - ; The state for evaluating the if statement's statements is the state after evaluating the if statement's condition (side effects challenge) |
388 | | - (evaluate-statement-list->state |
389 | | - (list (get-if-then arglist)) |
390 | | - (get-state-from-pair eval-ifcond) |
391 | | - cfuncsinstance)) |
392 | | - |
| 393 | + (evaluate-statement-list->state (list (get-if-then arglist)) |
| 394 | + (get-state-from-pair eval-ifcond) |
| 395 | + cfuncsinstance)) |
393 | 396 | ((has-else? arglist) |
394 | | - (evaluate-statement-list->state |
395 | | - (list (get-if-else arglist)) |
396 | | - (get-state-from-pair eval-ifcond) |
397 | | - cfuncsinstance)) |
398 | | - |
399 | | - ; If the if condition is false, return '() for the return value, and also return the updated state after evaluating the condition (side effects challenge) |
| 397 | + (evaluate-statement-list->state (list (get-if-else arglist)) |
| 398 | + (get-state-from-pair eval-ifcond) |
| 399 | + cfuncsinstance)) |
400 | 400 | (else (get-state-from-pair eval-ifcond)))))) |
401 | 401 |
|
| 402 | +; Checks if an arglist has an if-else branch |
402 | 403 | (define get-if-else |
403 | 404 | (lambda (arglist) |
404 | 405 | (cond |
405 | 406 | ((not (has-else? arglist)) (error "no else statement")) |
406 | 407 | (else (get-args-after-if-else arglist))))) |
407 | 408 |
|
| 409 | +; Checks if an arglist has an else branch |
408 | 410 | (define has-else? |
409 | 411 | (lambda (arglist) |
410 | 412 | (pair? (get-else-from-if-else arglist)))) |
|
424 | 426 | (evaluate-inner-try-statement arglist |
425 | 427 | state |
426 | 428 | (lambda (s) |
427 | | - (throw (G-remove-scope-from-state->state(evaluate-statement-list->state(get-finally-from-try arglist) |
428 | | - (G-add-empty-scope-to-state->state s) |
429 | | - cfuncsinstance)))) |
| 429 | + (throw (G-remove-scope-from-state->state (evaluate-statement-list->state (get-finally-from-try arglist) |
| 430 | + (G-add-empty-scope-to-state->state s) |
| 431 | + cfuncsinstance)))) |
430 | 432 | cfuncsinstance))))) |
431 | 433 |
|
| 434 | +; Evaluate an inner try statement |
432 | 435 | (define evaluate-inner-try-statement |
433 | 436 | (lambda (arglist state finally cfuncsinstance) |
434 | 437 | (finally |
435 | | - (G-remove-scope-from-state->state |
436 | | - (evaluate-statement-list->state (get-statements-from-try arglist) |
437 | | - (G-add-empty-scope-to-state->state state) |
438 | | - (cfuncs-update-catch cfuncsinstance |
439 | | - (lambda (s e) |
440 | | - (finally |
441 | | - (G-remove-scope-from-state->state |
442 | | - (evaluate-statement-list->state |
443 | | - (get-statements-from-catch (get-catch-from-try arglist)) |
444 | | - (G-push-state->state (get-exception-from-catch (get-catch-from-try arglist)) |
445 | | - e |
446 | | - (G-add-empty-scope-to-state->state (G-remove-scope-from-state->state s))) |
447 | | - cfuncsinstance)))))))))) |
448 | | - |
| 438 | + (G-remove-scope-from-state->state (evaluate-statement-list->state (get-statements-from-try arglist) |
| 439 | + (G-add-empty-scope-to-state->state state) |
| 440 | + (cfuncs-update-catch cfuncsinstance |
| 441 | + (lambda (s e) |
| 442 | + (finally |
| 443 | + (G-remove-scope-from-state->state (evaluate-statement-list->state |
| 444 | + (get-statements-from-catch (get-catch-from-try arglist)) |
| 445 | + (G-push-state->state (get-exception-from-catch (get-catch-from-try arglist)) |
| 446 | + e |
| 447 | + (G-add-empty-scope-to-state->state (G-remove-scope-from-state->state s))) |
| 448 | + cfuncsinstance)))))))))) |
| 449 | + |
| 450 | +; Gets the catch statement from try |
449 | 451 | (define get-catch-from-try |
450 | 452 | (lambda (arglist) |
451 | 453 | (cond |
452 | 454 | ((null? (get-catch-wrapper arglist)) '()) |
453 | 455 | (else (get-inner-catch-statement (get-contents-of-catch arglist)))))) |
454 | 456 |
|
| 457 | +; Gets the finally statement from try |
455 | 458 | (define get-finally-from-try |
456 | 459 | (lambda (arglist) |
457 | 460 | (cond |
|
474 | 477 | (lambda (break) |
475 | 478 | (evaluate-recursive-while arglist state (cfuncs-update-break cfuncsinstance break)))))) |
476 | 479 |
|
| 480 | + |
| 481 | +; Evaluate a while statement |
477 | 482 | (define evaluate-recursive-while |
478 | 483 | (lambda (arglist state cfuncsinstance) |
479 | 484 | (call/cc |
480 | 485 | (lambda (endcontinue) |
481 | 486 | (let* ([eval-while-cond (G-eval-atomic-statement->value_state (get-while-cond arglist) state cfuncsinstance)]) |
482 | 487 | (cond |
483 | | - ; If the while condition is true, evaluate the statements inside of it. |
484 | 488 | ((get-value-from-pair eval-while-cond) |
485 | | - (evaluate-recursive-while |
486 | | - arglist |
487 | | - ; The state for evaluating the while statement's statements is the state after evaluating the while statement's condition (side effects challenge) |
488 | | - (evaluate-statement-list->state |
489 | | - (list (get-while-statement arglist)) |
490 | | - (get-state-from-pair eval-while-cond) |
491 | | - |
492 | | - ; s is a passed in state |
493 | | - (cfuncs-update-continue |
494 | | - cfuncsinstance |
495 | | - (lambda (s) (endcontinue (evaluate-recursive-while arglist s cfuncsinstance))))) |
496 | | - |
497 | | - cfuncsinstance)) |
498 | | - |
| 489 | + (evaluate-recursive-while arglist |
| 490 | + (evaluate-statement-list->state (list (get-while-statement arglist)) |
| 491 | + (get-state-from-pair eval-while-cond) |
| 492 | + (cfuncs-update-continue cfuncsinstance |
| 493 | + (lambda (s) |
| 494 | + (endcontinue (evaluate-recursive-while arglist |
| 495 | + s |
| 496 | + cfuncsinstance))))) |
| 497 | + |
| 498 | + cfuncsinstance)) |
499 | 499 | ; If the while condition is false, return '() for the return value, and also return the updated state after evaluating the condition (side effects challenge) |
500 | 500 | (else (get-state-from-pair eval-while-cond)))))))) |
501 | 501 |
|
|
531 | 531 | (lambda (value state) |
532 | 532 | (let* ([cn (cadr value)]) |
533 | 533 | (cond |
534 | | - (else (list (list 'classname cn) (G-eval-class-closure->state cn state))))))) |
| 534 | + (else (list (list 'classname cn) |
| 535 | + (G-eval-class-closure->state cn state))))))) |
535 | 536 |
|
536 | 537 |
|
537 | 538 | ; Pushes the declaration statement to the state |
538 | 539 | (define declare-var->state |
539 | 540 | (lambda (name state) |
540 | | - (initialize-var->state name '() state))) |
| 541 | + (initialize-var->state name empty-value-for-declare state))) |
| 542 | + |
| 543 | +(define empty-value-for-declare '()) |
541 | 544 |
|
542 | 545 | ; Pushes and initializes the variable to the state |
543 | 546 | (define initialize-var->state |
544 | 547 | (lambda (name value state) |
545 | | - (cons (append-head-scope-to-scope (list (list name) (list value)) (get-top-scope state)) (get-tail-scope state)))) |
| 548 | + (cons (append-head-scope-to-scope (list (list name) |
| 549 | + (list value)) |
| 550 | + (get-top-scope state)) |
| 551 | + (get-tail-scope state)))) |
546 | 552 |
|
547 | 553 | ; Determines if an argument is a declare (and not an assign). |
548 | 554 | (define only-declare? |
|
584 | 590 | (lambda (arglist) |
585 | 591 | (eq? (get-value-from-pair (get-value-from-pair arglist)) 'classname))) |
586 | 592 |
|
| 593 | +; checks if an arglist is a dot-expression |
587 | 594 | (define dot-expr? |
588 | 595 | (lambda (arglist) |
589 | 596 | (cond |
|
597 | 604 | (arglist-tail arglist))) |
598 | 605 |
|
599 | 606 |
|
| 607 | +; evaluates a dotted expression |
600 | 608 | (define evaluate-dotted-expr->value_state |
601 | 609 | (lambda (arglist state cfuncsinstance) |
602 | 610 | (cond |
603 | 611 | ((eq? (dotted-class-instance arglist) 'this) |
604 | | - (list (get-value-from-pair |
605 | | - (G-value-lookup->value_state (dotted-class-call arglist) (get-valid-this-call-state state) cfuncsinstance)) |
| 612 | + (list (get-value-from-pair (G-value-lookup->value_state (dotted-class-call arglist) |
| 613 | + (get-valid-this-call-state state) |
| 614 | + cfuncsinstance)) |
606 | 615 | state)) |
607 | 616 | ((eq? (dotted-class-instance arglist) 'super) |
608 | | - (list (get-value-from-pair |
609 | | - (G-value-lookup->value_state (dotted-class-call arglist) (get-tail-scope (get-valid-this-call-state state)) cfuncsinstance)) |
| 617 | + (list (get-value-from-pair (G-value-lookup->value_state (dotted-class-call arglist) |
| 618 | + (get-tail-scope (get-valid-this-call-state state)) |
| 619 | + cfuncsinstance)) |
610 | 620 | state)) |
611 | | - (else (list (get-value-from-pair |
612 | | - (G-value-lookup->value_state (dotted-class-call arglist) (G-get-instance-state (dotted-class-instance arglist) state) cfuncsinstance)) |
613 | | - state))))) |
| 621 | + (else |
| 622 | + (list (get-value-from-pair (G-value-lookup->value_state (dotted-class-call arglist) |
| 623 | + (G-get-instance-state (dotted-class-instance arglist) state) |
| 624 | + cfuncsinstance)) |
| 625 | + state))))) |
614 | 626 |
|
615 | 627 | ; FUNCALL Section |
616 | 628 |
|
|
682 | 694 | (get-state-from-pair evaluate-assign)) cfuncsinstance)) |
683 | 695 | (else (error "variable undeclared args:" arglist "state" state)))))) |
684 | 696 |
|
| 697 | +; Evaluates a dotted assignment expression |
685 | 698 | (define evaluate-dotted-assign->value_state |
686 | 699 | (lambda (dot-expression assign-value state cfuncsinstance) |
687 | 700 | (cond |
688 | 701 | ((eq? (dotted-class-instance dot-expression) 'super) |
689 | | - (let* ([evaled-assign (G-eval-assign->value_state `(= ,(dotted-class-call dot-expression) ,assign-value) (get-tail-scope (get-valid-this-call-state state)) cfuncsinstance)] |
| 702 | + (let* ([evaled-assign (G-eval-assign->value_state `(= ,(dotted-class-call dot-expression) ,assign-value) |
| 703 | + (get-tail-scope (get-valid-this-call-state state)) |
| 704 | + cfuncsinstance)] |
690 | 705 | ; tail-scope is called to remove .cf pointer |
691 | 706 | [evaled-state (get-state-from-pair evaled-assign)] |
692 | 707 | [evaled-value (get-value-from-pair evaled-assign)]) |
693 | | - |
694 | | - (list evaled-value (G-merge-states->state state evaled-state)))) |
| 708 | + (list evaled-value (G-merge-states->state state evaled-state)))) |
| 709 | + |
695 | 710 | ((eq? (dotted-class-instance dot-expression) 'this) |
696 | | - (let* ([evaled-assign (G-eval-assign->value_state `(= ,(dotted-class-call dot-expression) ,assign-value) (get-valid-this-call-state state) cfuncsinstance)] |
| 711 | + (let* ([evaled-assign (G-eval-assign->value_state `(= ,(dotted-class-call dot-expression) ,assign-value) |
| 712 | + (get-valid-this-call-state state) |
| 713 | + cfuncsinstance)] |
697 | 714 | ; tail-scope is called to remove .cf pointer |
698 | 715 | [evaled-state (get-state-from-pair evaled-assign)] |
699 | 716 | [evaled-value (get-value-from-pair evaled-assign)]) |
700 | | - |
701 | | - (list evaled-value (G-merge-states->state state evaled-state)))) |
| 717 | + (list evaled-value (G-merge-states->state state evaled-state)))) |
| 718 | + |
702 | 719 | (else |
703 | 720 | (update-class-instance (dotted-class-instance dot-expression) |
704 | | - (extract-new-class-instance-state (get-state-from-pair |
705 | | - (G-eval-assign->value_state `(= ,(dotted-class-call dot-expression) ,assign-value) (construct-dotted-state dot-expression state) cfuncsinstance))) |
706 | | - state))))) |
707 | | - |
708 | | - |
709 | | - |
| 721 | + (extract-new-class-instance-state (get-state-from-pair G-eval-assign->value_state |
| 722 | + `(= ,(dotted-class-call dot-expression) ,assign-value) |
| 723 | + (construct-dotted-state dot-expression state) |
| 724 | + cfuncsinstance))) |
| 725 | + state)))) |
710 | 726 |
|
711 | 727 | ; Determines whether or not an assignment argument is reached |
712 | 728 | (define G-assign? |
|
739 | 755 | ((eq? (length arglist) 2) |
740 | 756 | (eval-expr-uni->value_state (get-op-from-expr arglist) |
741 | 757 | (get-arg1-from-expr arglist) |
742 | | - state cfuncsinstance)) |
| 758 | + state |
| 759 | + cfuncsinstance)) |
743 | 760 | ((eq? (length arglist) 3) |
744 | 761 | (eval-expr-multi->value_state (get-op-from-expr arglist) |
745 | 762 | (get-arg1-from-expr arglist) |
746 | 763 | (get-arg2-from-expr arglist) |
747 | | - state cfuncsinstance)) |
| 764 | + state |
| 765 | + cfuncsinstance)) |
748 | 766 | (else (error "invalid number of arguments"))))) |
749 | 767 |
|
750 | 768 |
|
|
821 | 839 | ; We return a (value, state), hence the cons for the value and the state |
822 | 840 | ; The value is derived from applying the operator on arg1 and arg2 |
823 | 841 | ; To handle side effects, the state passed into arg2 is the state after evaluating arg1 |
824 | | - ((and (eq? (G-type-lookup arg1 state cfuncsinstance) 'boolean) (eq? (G-type-lookup arg2 state cfuncsinstance) 'boolean)) |
| 842 | + ((and (eq? (G-type-lookup arg1 state cfuncsinstance) 'boolean) |
| 843 | + (eq? (G-type-lookup arg2 state cfuncsinstance) 'boolean)) |
825 | 844 | (cons ((boolean-operator-to-function-multi op) |
826 | 845 | (get-value-from-pair lookup-arg1) |
827 | 846 | (get-value-from-pair lookup-arg2)) |
|
835 | 854 | (define eval-math-expr-multi->value_state |
836 | 855 | (lambda (op arg1 arg2 state cfuncsinstance) |
837 | 856 | (cond |
838 | | - ((and (eq? (G-type-lookup arg1 state cfuncsinstance) 'integer) (eq? (G-type-lookup arg2 state cfuncsinstance) 'integer)) |
| 857 | + ((and (eq? (G-type-lookup arg1 state cfuncsinstance) 'integer) |
| 858 | + (eq? (G-type-lookup arg2 state cfuncsinstance) 'integer)) |
839 | 859 | (eval-math-expr-int-multi->value_state op arg1 arg2 state cfuncsinstance)) |
840 | 860 | (else (error "invalid types for math expression"))))) |
841 | 861 |
|
|
0 commit comments