@@ -33,9 +33,7 @@ import {
3333 ifStatementElseBlock ,
3434 indexingExprArrayExpr ,
3535 indexingExprIndexExpr ,
36- infixOpExprLhs ,
3736 infixOpExprOpName ,
38- infixOpExprRhs ,
3937 intLitExprValue ,
4038 isBlock ,
4139 isEmptyPlaceholder ,
@@ -70,7 +68,6 @@ import {
7068} from "./boolify" ;
7169import {
7270 ArrayElementCell ,
73- assign ,
7471 Cell ,
7572 VarCell ,
7673} from "./cell" ;
@@ -90,7 +87,6 @@ import {
9087import {
9188 E000_InternalError ,
9289 E500_OutOfFuel ,
93- E601_ZeroDivisionError ,
9490 E603_TypeError ,
9591 E604_IndexError ,
9692 E607_CannotAssignError ,
@@ -103,6 +99,7 @@ import {
10399 E614_MacroAtRuntimeError ,
104100} from "./error" ;
105101import {
102+ assertNotAssignable ,
106103 cloneJumpMap ,
107104 Frame ,
108105 JumpMap ,
@@ -111,6 +108,9 @@ import {
111108 recurse ,
112109 tailRecurse ,
113110} from "./frame" ;
111+ import {
112+ infixOpMap ,
113+ } from "./infix" ;
114114import {
115115 prefixOpMap ,
116116} from "./prefix" ;
@@ -119,9 +119,6 @@ import {
119119 isStatementKind ,
120120 kindAndPayloadOfNode ,
121121} from "./reify" ;
122- import {
123- stringify ,
124- } from "./stringify" ;
125122import {
126123 ArrayValue ,
127124 BoolValue ,
@@ -192,8 +189,6 @@ export function initializeEnv(
192189 return env ;
193190}
194191
195- const comparisonOps = new Set ( [ "<" , "<=" , ">" , ">=" , "==" , "!=" ] ) ;
196-
197192function load (
198193 compUnit : SyntaxNode ,
199194 staticEnvs : Map < SyntaxNode , Env > ,
@@ -207,14 +202,6 @@ function load(
207202 ) ;
208203}
209204
210- function assertNotAssignable ( frame : Frame ) {
211- if ( frame . mode === Mode . GetCell ) {
212- throw new E607_CannotAssignError (
213- "Cannot assign to " + frame . node . kind . name
214- ) ;
215- }
216- }
217-
218205function zip < T , U > ( ts : Array < T > , us : Array < U > ) : Array < [ T , U ] > {
219206 if ( ts . length !== us . length ) {
220207 throw new E000_InternalError (
@@ -609,263 +596,14 @@ handlerMap.set(SyntaxKind.PREFIX_OP_EXPR, (frame) => {
609596} ) ;
610597
611598handlerMap . set ( SyntaxKind . INFIX_OP_EXPR , ( frame ) => {
612- // let lhs = infixOpExprLhs(node);
613- // let opName = infixOpExprOpName(node).payload as string;
614- // let rhs = infixOpExprRhs(node);
615- // if (opName !== "=") {
616- // assertNotAssignable();
617- // }
618- // if (["+", "-", "*", "//", "%"].includes(opName)) { // [0]
619- // let left = eval(lhs);
620- // if (!(left instanceof IntValue)) { // [1]
621- // throw new E603_TypeError(`Expected Int as lhs of ${opName}`);
622- // }
623- // let right = eval(rhs);
624- // if (!(right instanceof IntValue)) { // [2]
625- // throw new E603_TypeError(`Expected Int as rhs of ${opName}`);
626- // }
627- // if (opName === "+") {
628- // return new IntValue(left.payload + right.payload);
629- // }
630- // else if (opName === "-") {
631- // return new IntValue(left.payload - right.payload);
632- // }
633- // else if (opName === "*") {
634- // return new IntValue(left.payload * right.payload);
635- // }
636- // else if (opName === "//") {
637- // if (!(right instanceof IntValue)) {
638- // throw new E603_TypeError("Expected Int as rhs of //");
639- // }
640- // if (right.payload === 0n) {
641- // throw new E601_ZeroDivisionError("Division by 0");
642- // }
643- // let negative = left.payload < 0n !== right.payload < 0n;
644- // let nonZeroMod = left.payload % right.payload !== 0n;
645- // let diff = negative && nonZeroMod ? 1n : 0n;
646- // return new IntValue(left.payload / right.payload - diff);
647- // }
648- // else if (opName === "%") {
649- // if (!(right instanceof IntValue)) {
650- // throw new E603_TypeError("Expected Int as rhs of %");
651- // }
652- // if (right.payload === 0n) {
653- // throw new E601_ZeroDivisionError("Division by 0");
654- // }
655- // return new IntValue(left.payload % right.payload);
656- // }
657- // else if (comparisonOps.has(opName)) {
658- // let compareResult = evaluateComparison(left, opName, right);
659- // return new BoolValue(compareResult);
660- // }
661- // }
662- // else if (opName === "~") {
663- // let left = eval(lhs);
664- // let strLeft = stringify(left); // [3]
665- // let right = eval(rhs);
666- // let strRight = stringify(right); // [4]
667- // return new StrValue(strLeft.payload + strRight.payload);
668- // }
669- // else if (comparisonOps.has(opName)) {
670- // let left = eval(lhs);
671- // let right = eval(rhs); // [7]
672- // // [8]
673- // let compareResult = evaluateComparison(left, opName, right);
674- // return new BoolValue(compareResult);
675- // }
676- // else if (opName === "&&") {
677- // let left = eval(lhs);
678- // return boolify(left) // [5]
679- // ? eval(rhs)
680- // : left;
681- // }
682- // }
683- // else if (opName === "||") {
684- // let left = eval(lhs);
685- // return boolify(left) // [6]
686- // ? left
687- // : eval(rhs);
688- // }
689- // else if (opName === "=") {
690- // let cell = evalCell(lhs);
691- // let value = eval(rhs); // [9]
692- // assign(cell, value); // [10]
693- // if (mode === Mode.GetValue) {
694- // return value;
695- // }
696- // else if (mode === Mode.GetCell) {
697- // return cell;
698- // }
699- // }
700- // else {
701- // throw new E000_InternalError(`Unknown infix op ${opName}`);
702- // }
703599 let opName = infixOpExprOpName ( frame . node ) . payload as string ;
704- if ( opName !== "=" ) {
705- assertNotAssignable ( frame ) ;
706- }
707- switch ( frame . state ) {
708- case 0 : {
709- if ( [ "+" , "-" , "*" , "//" , "%" ] . includes ( opName ) ) {
710- let lhs = infixOpExprLhs ( frame . node ) ;
711- return recurse ( frame , 1 , { node : lhs } ) ;
712- }
713- else if ( opName === "~" ) {
714- let lhs = infixOpExprLhs ( frame . node ) ;
715- return recurse ( frame , 3 , { node : lhs } ) ;
716- }
717- else if ( comparisonOps . has ( opName ) ) {
718- let lhs = infixOpExprLhs ( frame . node ) ;
719- return recurse ( frame , 7 , { node : lhs } ) ;
720- }
721- else if ( opName === "&&" ) {
722- let lhs = infixOpExprLhs ( frame . node ) ;
723- return recurse ( frame , 5 , { node : lhs } ) ;
724- }
725- else if ( opName === "||" ) {
726- let lhs = infixOpExprLhs ( frame . node ) ;
727- return recurse ( frame , 6 , { node : lhs } ) ;
728- }
729- else if ( opName === "=" ) {
730- let lhs = infixOpExprLhs ( frame . node ) ;
731- return recurse ( frame , 9 , { node : lhs , mode : Mode . GetCell } ) ;
732- }
733- else {
734- throw new E000_InternalError ( `Unknown infix op ${ opName } ` ) ;
735- }
736- }
737- case 1 : {
738- let left = frame . value ;
739- if ( ! ( left instanceof IntValue ) ) {
740- throw new E603_TypeError ( `Expected Int as lhs of ${ opName } ` ) ;
741- }
742- frame . v1 = left ;
743- let rhs = infixOpExprRhs ( frame . node ) ;
744- return recurse ( frame , 2 , { node : rhs } ) ;
745- }
746- case 2 : {
747- let left = frame . v1 as IntValue ;
748- let right = frame . value ;
749- if ( ! ( right instanceof IntValue ) ) {
750- throw new E603_TypeError ( `Expected Int as rhs of ${ opName } ` ) ;
751- }
752- if ( opName === "+" ) {
753- return frame . mode === Mode . Ignore
754- ? new NoneValue ( )
755- : new IntValue ( left . payload + right . payload ) ;
756- }
757- else if ( opName === "-" ) {
758- return frame . mode === Mode . Ignore
759- ? new NoneValue ( )
760- : new IntValue ( left . payload - right . payload ) ;
761- }
762- else if ( opName === "*" ) {
763- return frame . mode === Mode . Ignore
764- ? new NoneValue ( )
765- : new IntValue ( left . payload * right . payload ) ;
766- }
767- else if ( opName === "//" ) {
768- if ( ! ( right instanceof IntValue ) ) {
769- throw new E603_TypeError ( "Expected Int as rhs of //" ) ;
770- }
771- if ( right . payload === 0n ) {
772- throw new E601_ZeroDivisionError ( "Division by 0" ) ;
773- }
774- let negative = left . payload < 0n !== right . payload < 0n ;
775- let nonZeroMod = left . payload % right . payload !== 0n ;
776- let diff = negative && nonZeroMod ? 1n : 0n ;
777- return frame . mode === Mode . Ignore
778- ? new NoneValue ( )
779- : new IntValue ( left . payload / right . payload - diff ) ;
780- }
781- else if ( opName === "%" ) {
782- if ( ! ( right instanceof IntValue ) ) {
783- throw new E603_TypeError ( "Expected Int as rhs of %" ) ;
784- }
785- if ( right . payload === 0n ) {
786- throw new E601_ZeroDivisionError ( "Division by 0" ) ;
787- }
788- return frame . mode === Mode . Ignore
789- ? new NoneValue ( )
790- : new IntValue ( left . payload % right . payload ) ;
791- }
792- }
793- case 3 : {
794- let left = frame . value ;
795- let strLeft = stringify ( left ) ;
796- frame . v1 = strLeft ;
797- let rhs = infixOpExprRhs ( frame . node ) ;
798- return recurse ( frame , 4 , { node : rhs } ) ;
799- }
800- case 4 : {
801- let strLeft = frame . v1 as StrValue ;
802- let right = frame . value ;
803- let strRight = stringify ( right ) ;
804- return frame . mode === Mode . Ignore
805- ? new NoneValue ( )
806- : new StrValue ( strLeft . payload + strRight . payload ) ;
807- }
808- case 5 : {
809- let left = frame . value ;
810- let rhs = infixOpExprRhs ( frame . node ) ;
811- if ( boolify ( left ) ) {
812- return tailRecurse ( frame , { node : rhs } ) ;
813- }
814- else {
815- return frame . mode === Mode . Ignore
816- ? new NoneValue ( )
817- : left ;
818- }
819- }
820- case 6 : {
821- let left = frame . value ;
822- let rhs = infixOpExprRhs ( frame . node ) ;
823- if ( boolify ( left ) ) {
824- return frame . mode === Mode . Ignore
825- ? new NoneValue ( )
826- : left ;
827- }
828- else {
829- return tailRecurse ( frame , { node : rhs } ) ;
830- }
831- }
832- case 7 : {
833- let left = frame . value ;
834- frame . v1 = left ;
835- let rhs = infixOpExprRhs ( frame . node ) ;
836- return recurse ( frame , 8 , { node : rhs } ) ;
837- }
838- case 8 : {
839- let left = frame . v1 ;
840- let right = frame . value ;
841- let compareResult = evaluateComparison ( left , opName , right ) ;
842- return new BoolValue ( compareResult ) ;
843- }
844- case 9 : {
845- let rhs = infixOpExprRhs ( frame . node ) ;
846- return recurse ( frame , 10 , { node : rhs } ) ;
847- }
848- case 10 : {
849- let cell = frame . cell ! ;
850- let value = frame . value ;
851- assign ( cell , value ) ;
852- if ( frame . mode === Mode . GetValue ) {
853- return value ;
854- }
855- else if ( frame . mode === Mode . GetCell ) {
856- return cell ;
857- }
858- else if ( frame . mode === Mode . Ignore ) {
859- return new NoneValue ( ) ;
860- }
861- else {
862- throw new E000_InternalError (
863- `Unknown mode in '=' (${ frame . mode . name } )`
864- ) ;
865- }
866- }
600+ let handler = infixOpMap . get ( opName ) ;
601+ if ( handler === undefined ) {
602+ throw new E000_InternalError (
603+ `Missing handler for infix op '${ opName } '`
604+ ) ;
867605 }
868- throw new E000_InternalError ( "Unreachable state" ) ;
606+ return handler ( frame ) ;
869607} ) ;
870608
871609handlerMap . set ( SyntaxKind . CHAINED_OP_EXPR , ( frame ) => {
0 commit comments