Overview
Comment: | Implement the other kinds of pattern matching (=P) (P*) (,P*) (=P*) but it is untested so far. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c0f558d8e6b1e1cefa89cecab350a335 |
User & Date: | user on 2021-04-25 02:39:17 |
Other Links: | manifest | tags |
Context
2021-04-25
| ||
19:54 | Remove the "el ... if" block, which wasn't working. (Later, I may add a case block instead.) check-in: 932a5231ed user: user tags: trunk | |
02:39 | Implement the other kinds of pattern matching (=P) (P*) (,P*) (=P*) but it is untested so far. check-in: c0f558d8e6 user: user tags: trunk | |
2021-04-24
| ||
19:09 | Implement BroadcastAnd and BroadcastList instructions. check-in: a833709837 user: user tags: trunk | |
Changes
Modified class.doc from [f8fa26ffcf] to [dda42baf1a].
︙ | ︙ | |||
2109 2110 2111 2112 2113 2114 2115 | object as the origin of the movement, and that object's direction as the direction of movement. === Pattern matching === Where an instruction is expected, you can have pattern matching. This can | > | > > > | > > > | > > | > > > > > > > > > > > > | 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 | object as the origin of the movement, and that object's direction as the direction of movement. === Pattern matching === Where an instruction is expected, you can have pattern matching. This can be (<operator> <pattern...>) where the operator can be one of: P Find starting at the current location, with the current object's direction. Pushes the found object, or zero if not found. ,P Find starting at the specified object's location and direction. Pushes the found object, or zero if not found. =P Searches everywhere. Pushes the found object, or zero if not found. P* Like P but push all found objects, or pushes nothing if not found. ,P* Like ,P but push all found objects, or pushes nothing if not found. =P* Like =P but push all found objects, or pushes nothing if not found. Inside the pattern, the following commands are allowed (although the commands that push stuff to the stack should not be used in the patterns with P* or ,P* or =P*): <class> Match an object of the specified class. <dir> Move in the specified direction. (This does not move any objects; it only moves the cursor for pattern matching.) The direction can be |
︙ | ︙ |
Modified exec.c from [6dbd0b402f] to [834664aa2d].
︙ | ︙ | |||
1784 1785 1786 1787 1788 1789 1790 | case OP_OBJBOTTOMAT: n=obj_bottom_at(x,y); break; case OP_OBJTOPAT: n=obj_top_at(x,y); break; case OP_RET: | > > > > > > | > > > | | > > > > > > > > > > > > > > | 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 | case OP_OBJBOTTOMAT: n=obj_bottom_at(x,y); break; case OP_OBJTOPAT: n=obj_top_at(x,y); break; case OP_RET: if(all) { if(vstackptr>=VSTACKSIZE-1) Throw("Stack overflow"); if(n==VOIDLINK) n=obj_bottom_at(x,y); Push(OVALUE(n)); goto fail; } else { return n==VOIDLINK?obj_bottom_at(x,y):n; } break; case OP_SUB: if(vstackptr>=VSTACKSIZE-1) Throw("Stack overflow"); Push(NVALUE(0)); break; case OP_THEN: // This opcode does nothing break; case OP_TRACE: if(main_options['t']) { printf("ptr=%d cpi=%d x=%d y=%d dir=%d obj=%lu ",ptr,cpi,x,y,d,(long)n); printf("[ptr=%d x=%d y=%d dir=%d]\n",cp[cpi].ptr,cp[cpi].x,cp[cpi].y,cp[cpi].dir); } break; default: Throw("Unimplemented opcode in pattern"); } goto again; fail: if(!all) { if(vstackptr<cp->depth) Throw("Stack underflow in pattern matching"); vstackptr=cp[cpi].depth; } if(!cpi) return VOIDLINK; x=cp[cpi].x; y=cp[cpi].y; d=cp[cpi].dir; ptr=cp[cpi].ptr; n=VOIDLINK; cpi--; goto again; } static Uint32 v_pattern_anywhere(Uint16*code,int ptr,char all) { int i; Uint32 n; for(i=0;i<pfheight*64;i++) { n=playfield[i]; if(n!=VOIDLINK) { n=v_pattern(code,ptr,n,all); if(n!=VOIDLINK && !all) return n; } } return VOIDLINK; } // Here is where the execution of a Free Hero Mesh bytecode subroutine is executed. #define NoIgnore() do{ changed=1; }while(0) #define GetVariableOf(a,b) (i=v_object(Pop()),i==VOIDLINK?NVALUE(0):b(objects[i]->a)) #define GetVariableOrAttributeOf(a,b) (t2=Pop(),t2.t==TY_CLASS?NVALUE(classes[t2.u]->a):(i=v_object(t2),i==VOIDLINK?NVALUE(0):b(objects[i]->a))) #define Numeric(a) do{ if((a).t!=TY_NUMBER) Throw("Type mismatch"); }while(0) #define DivideBy(a) do{ Numeric(a); if(!(a).u) Throw("Division by zero"); }while(0) |
︙ | ︙ | |||
2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 | case OP_OBJDIR_C: StackReq(2,1); t2=Pop(); Numeric(t2); i=obj_dir(v_object(Pop()),t2.u); Push(OVALUE(i)); break; case OP_OBJLAYERAT: StackReq(3,1); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); i=obj_layer_at(t1.u,t2.u,t3.u); Push(OVALUE(i)); break; case OP_OBJMOVINGTO: StackReq(2,0); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); v_obj_moving_to(t1.u,t2.u); break; case OP_OBJTOPAT: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); i=obj_top_at(t1.u,t2.u); Push(OVALUE(i)); break; case OP_OVER: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t1); Push(t2); Push(t1); break; case OP_PATTERN: StackReq(0,1); i=code[ptr++]; j=v_pattern(code,ptr,obj,0); ptr=i; Push(OVALUE(j)); break; case OP_PATTERN_C: StackReq(1,1); i=code[ptr++]; j=v_object(Pop()); if(j!=VOIDLINK) j=v_pattern(code,ptr,j,0); ptr=i; Push(OVALUE(j)); break; case OP_PICK: StackReq(0,1); t1=Pop(); Numeric(t1); if(t1.u>=vstackptr) Throw("Stack index out of range"); t1=vstack[vstackptr-t1.u-1]; Push(t1); break; case OP_PLAYER: StackReq(0,1); if(classes[o->class]->cflags&CF_PLAYER) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_PLAYER_C: StackReq(1,1); GetClassFlagOf(CF_PLAYER); break; case OP_PLUSMOVE: StackReq(1,1); t1=Pop(); Numeric(t1); i=defer_move(obj,t1.u,1); Push(NVALUE(i)); break; case OP_PLUSMOVE_C: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); i=defer_move(i,t1.u,1); Push(NVALUE(i)); break; case OP_PLUSMOVE_D: StackReq(1,0); t1=Pop(); Numeric(t1); defer_move(obj,t1.u,1); break; case OP_PLUSMOVE_CD: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); defer_move(i,t1.u,1); break; | > > > > | 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 | case OP_OBJDIR_C: StackReq(2,1); t2=Pop(); Numeric(t2); i=obj_dir(v_object(Pop()),t2.u); Push(OVALUE(i)); break; case OP_OBJLAYERAT: StackReq(3,1); t3=Pop(); Numeric(t3); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); i=obj_layer_at(t1.u,t2.u,t3.u); Push(OVALUE(i)); break; case OP_OBJMOVINGTO: StackReq(2,0); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); v_obj_moving_to(t1.u,t2.u); break; case OP_OBJTOPAT: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); i=obj_top_at(t1.u,t2.u); Push(OVALUE(i)); break; case OP_OVER: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t1); Push(t2); Push(t1); break; case OP_PATTERN: StackReq(0,1); i=code[ptr++]; j=v_pattern(code,ptr,obj,0); ptr=i; Push(OVALUE(j)); break; case OP_PATTERN_C: StackReq(1,1); i=code[ptr++]; j=v_object(Pop()); if(j!=VOIDLINK) j=v_pattern(code,ptr,j,0); ptr=i; Push(OVALUE(j)); break; case OP_PATTERN_E: StackReq(0,1); i=code[ptr++]; j=v_pattern_anywhere(code,ptr,0); ptr=i; Push(OVALUE(j)); break; case OP_PATTERNS: StackReq(0,1); i=code[ptr++]; v_pattern(code,ptr,obj,1); ptr=i; break; case OP_PATTERNS_C: StackReq(1,1); i=code[ptr++]; j=v_object(Pop()); if(j!=VOIDLINK) v_pattern(code,ptr,j,1); ptr=i; break; case OP_PATTERNS_E: StackReq(0,1); i=code[ptr++]; v_pattern_anywhere(code,ptr,1); ptr=i; break; case OP_PICK: StackReq(0,1); t1=Pop(); Numeric(t1); if(t1.u>=vstackptr) Throw("Stack index out of range"); t1=vstack[vstackptr-t1.u-1]; Push(t1); break; case OP_PLAYER: StackReq(0,1); if(classes[o->class]->cflags&CF_PLAYER) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_PLAYER_C: StackReq(1,1); GetClassFlagOf(CF_PLAYER); break; case OP_PLUSMOVE: StackReq(1,1); t1=Pop(); Numeric(t1); i=defer_move(obj,t1.u,1); Push(NVALUE(i)); break; case OP_PLUSMOVE_C: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); i=defer_move(i,t1.u,1); Push(NVALUE(i)); break; case OP_PLUSMOVE_D: StackReq(1,0); t1=Pop(); Numeric(t1); defer_move(obj,t1.u,1); break; case OP_PLUSMOVE_CD: StackReq(2,1); t1=Pop(); Numeric(t1); i=v_object(Pop()); defer_move(i,t1.u,1); break; |
︙ | ︙ |