Guest User

Untitled

a guest
Jun 24th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.14 KB | None | 0 0
  1. import std.algorithm;
  2. import std.string;
  3. import std.array;
  4. import std.regex;
  5. import std.range;
  6. import std.stdio;
  7.  
  8. struct Stack(T) {
  9. T[] stack;
  10.  
  11. @property T pop() {
  12. T t = stack[$ - 1];
  13. stack.length--;
  14. return t;
  15. }
  16.  
  17. @property size_t length() {
  18. return stack.length;
  19. }
  20.  
  21. @property void push(T value) {
  22. stack ~= value;
  23. }
  24.  
  25. @property bool empty() {
  26. return stack.empty;
  27. }
  28.  
  29. @property T front() {
  30. return pop;
  31. }
  32.  
  33. @property void popFront() {
  34. pop;
  35. }
  36.  
  37. @property void popAll() {
  38. foreach (_; this) {
  39. }
  40. }
  41. }
  42.  
  43. struct Registers {
  44. int a;
  45. int b;
  46. int c;
  47. int d;
  48. int e;
  49. int f;
  50. }
  51.  
  52. enum Register {
  53. A,
  54. B,
  55. C,
  56. D,
  57. E,
  58. F
  59. }
  60.  
  61. enum InstructionType {
  62. Func,
  63. CallF,
  64. CallFA,
  65. CallFAR,
  66. HLT,
  67. Print,
  68. Eq,
  69. Neq,
  70. Leq,
  71. Geq,
  72. Lt,
  73. Gt,
  74. EqI,
  75. NeqI,
  76. LeqI,
  77. GeqI,
  78. LtI,
  79. GtI,
  80. If,
  81. RetR,
  82. RetI,
  83. AddR,
  84. AddI,
  85. SubR,
  86. SubI,
  87. MulR,
  88. MulI,
  89. MovR,
  90. MovI,
  91. PopTo,
  92. PushR,
  93. PushI
  94. }
  95.  
  96. interface Instruction {
  97. InstructionType type();
  98. }
  99.  
  100. class Func : Instruction {
  101. int id;
  102. Instruction[] proc;
  103. this(int id, Instruction[] proc) {
  104. this.id = id;
  105. this.proc = proc;
  106. }
  107.  
  108. InstructionType type() {
  109. return InstructionType.Func;
  110. }
  111. }
  112.  
  113. Instruction func(int id, Instruction[] proc) {
  114. return new Func(id, proc);
  115. }
  116.  
  117. class CallF : Instruction {
  118. int id;
  119. this(int id) {
  120. this.id = id;
  121. }
  122.  
  123. InstructionType type() {
  124. return InstructionType.CallF;
  125. }
  126. }
  127.  
  128. Instruction callf(int id) {
  129. return new CallF(id);
  130. }
  131.  
  132. class CallFA : Instruction {
  133. int id;
  134. int[] args;
  135. this(int id, int[] args) {
  136. this.id = id;
  137. this.args = args;
  138. }
  139.  
  140. InstructionType type() {
  141. return InstructionType.CallFA;
  142. }
  143. }
  144.  
  145. Instruction callfa(int id, int[] args) {
  146. return new CallFA(id, args);
  147. }
  148.  
  149. class CallFAR : Instruction {
  150. int id;
  151. Register[] args;
  152. this(int id, Register[] args) {
  153. this.id = id;
  154. this.args = args;
  155. }
  156.  
  157. InstructionType type() {
  158. return InstructionType.CallFAR;
  159. }
  160. }
  161.  
  162. Instruction callfar(int id, Register[] args) {
  163. return new CallFAR(id, args);
  164. }
  165.  
  166. class HLT : Instruction {
  167. InstructionType type() {
  168. return InstructionType.HLT;
  169. }
  170. }
  171.  
  172. HLT hlt() {
  173. return new HLT;
  174. }
  175.  
  176. string opR(string className)() {
  177. string helperName = className.toLower;
  178. return `
  179. class ` ~ className ~ ` : Instruction {
  180. Register r;
  181. this(Register r) {
  182. this.r = r;
  183. }
  184.  
  185. InstructionType type() {
  186. return InstructionType.` ~ className ~ `;
  187. }
  188. }
  189.  
  190. Instruction ` ~ helperName
  191. ~ `(Register r) {
  192. return new ` ~ className ~ `(r);
  193. }`;
  194. }
  195.  
  196. string opI(string className)() {
  197. string helperName = className.toLower;
  198. return `
  199. class ` ~ className ~ ` : Instruction {
  200. int i;
  201. this(int i) {
  202. this.i = i;
  203. }
  204.  
  205. InstructionType type() {
  206. return InstructionType.` ~ className ~ `;
  207. }
  208. }
  209.  
  210. Instruction ` ~ helperName
  211. ~ `(int i) {
  212. return new ` ~ className ~ `(i);
  213. }`;
  214. }
  215.  
  216. string opR2(string className)() {
  217. string helperName = className.toLower;
  218. return `
  219. class ` ~ className ~ ` : Instruction {
  220. Register r1, r2;
  221. this(Register r1, Register r2) {
  222. this.r1 = r1;
  223. this.r2 = r2;
  224. }
  225.  
  226. InstructionType type() {
  227. return InstructionType.` ~ className ~ `;
  228. }
  229. }
  230.  
  231. Instruction ` ~ helperName
  232. ~ `(Register r1, Register r2) {
  233. return new ` ~ className ~ `(r1, r2);
  234. }`;
  235. }
  236.  
  237. string opRI(string className)() {
  238. string helperName = className.toLower;
  239. return `
  240. class ` ~ className ~ ` : Instruction {
  241. Register r;
  242. int i;
  243. this(Register r, int i) {
  244. this.r = r;
  245. this.i = i;
  246. }
  247.  
  248. InstructionType type() {
  249. return InstructionType.` ~ className ~ `;
  250. }
  251. }
  252.  
  253. Instruction ` ~ helperName
  254. ~ `(Register r, int i) {
  255. return new ` ~ className ~ `(r, i);
  256. }`;
  257. }
  258.  
  259. mixin(opR!("Print"));
  260. mixin(opR2!("Eq"));
  261. mixin(opR2!("Neq"));
  262. mixin(opR2!("Leq"));
  263. mixin(opR2!("Geq"));
  264. mixin(opR2!("Lt"));
  265. mixin(opR2!("Gt"));
  266. mixin(opRI!("EqI"));
  267. mixin(opRI!("NeqI"));
  268. mixin(opRI!("LeqI"));
  269. mixin(opRI!("GeqI"));
  270. mixin(opRI!("LtI"));
  271. mixin(opRI!("GtI"));
  272.  
  273. class If : Instruction {
  274. Register r;
  275. Instruction[][] insts;
  276. this(Register r, Instruction[][] insts) {
  277. this.r = r;
  278. this.insts = insts;
  279. }
  280.  
  281. InstructionType type() {
  282. return InstructionType.If;
  283. }
  284. }
  285.  
  286. Instruction _if(Register r, Instruction[][] insts) {
  287. return new If(r, insts);
  288. }
  289.  
  290. mixin(opR!("RetR"));
  291. mixin(opI!("RetI"));
  292. mixin(opR2!("AddR"));
  293. mixin(opRI!("AddI"));
  294. mixin(opR2!("SubR"));
  295. mixin(opRI!("SubI"));
  296. mixin(opR2!("MulR"));
  297. mixin(opRI!("MulI"));
  298. mixin(opR2!("MovR"));
  299. mixin(opRI!("MovI"));
  300. mixin(opR!("PopTo"));
  301. mixin(opR!("PushR"));
  302. mixin(opI!("PushI"));
  303.  
  304. Stack!int stack = Stack!int();
  305. Registers registers;
  306. Instruction[][int] functions;
  307.  
  308. void setRegister(Register r, int v) {
  309. final switch (r) with (Register) {
  310. case A:
  311. registers.a = v;
  312. break;
  313. case B:
  314. registers.b = v;
  315. break;
  316. case C:
  317. registers.c = v;
  318. break;
  319. case D:
  320. registers.d = v;
  321. break;
  322. case E:
  323. registers.e = v;
  324. break;
  325. case F:
  326. registers.f = v;
  327. break;
  328. }
  329. }
  330.  
  331. int getRegister(Register r) {
  332. final switch (r) with (Register) {
  333. case A:
  334. return registers.a;
  335. case B:
  336. return registers.b;
  337. case C:
  338. return registers.c;
  339. case D:
  340. return registers.d;
  341. case E:
  342. return registers.e;
  343. case F:
  344. return registers.f;
  345. }
  346. }
  347.  
  348. void popTo(ref Stack!int stack, Register r) {
  349. if (stack.empty) {
  350. setRegister(r, 0);
  351. }
  352. else {
  353. int x = stack.pop;
  354. setRegister(r, x);
  355. }
  356. }
  357.  
  358. void reduceStack(ref Stack!int stack, int result, int function(int, int) f) {
  359. if (stack.empty) {
  360. stack.push(result);
  361. }
  362. else {
  363. int x = stack.pop;
  364. reduceStack(stack, f(result, x), f);
  365. }
  366. }
  367.  
  368. void saveFunction(int id, Instruction[] insts) {
  369. functions[id] = insts;
  370. }
  371.  
  372. Instruction[] getFunction(int id) {
  373. return functions[id];
  374. }
  375.  
  376. /*
  377. 関数を呼ぶ場合,
  378. F -> 第1引数
  379. E -> 第2引数
  380. D -> 第3引数
  381. C -> 第4引数
  382. */
  383.  
  384. void setArgs(int[] args) {
  385. with (Register) {
  386. Register[] rs = [F, E, D, C];
  387. foreach (i, v; args) {
  388. setRegister(rs[i], v);
  389. }
  390. }
  391. }
  392.  
  393. void compOpR2(T, alias pred)(Instruction inst) {
  394. T v = cast(T)inst;
  395. Register x = v.r1, y = v.r2;
  396. if (pred(getRegister(x), getRegister(y))) {
  397. setRegister(Register.B, 1);
  398. }
  399. else {
  400. setRegister(Register.B, 0);
  401. }
  402. }
  403.  
  404. void compOpRI(T, alias pred)(Instruction inst) {
  405. T v = cast(T)inst;
  406. Register x = v.r;
  407. int y = v.i;
  408. if (pred(getRegister(x), y)) {
  409. setRegister(Register.B, 1);
  410. }
  411. else {
  412. setRegister(Register.B, 0);
  413. }
  414. }
  415.  
  416. void arithmaticOpR2(T, alias pred)(Instruction inst) {
  417. T v = cast(T)inst;
  418. Register x = v.r1, y = v.r2;
  419. setRegister(Register.A, pred(getRegister(x), getRegister(y)));
  420. }
  421.  
  422. void arithmaticOpRI(T, alias pred)(Instruction inst) {
  423. T v = cast(T)inst;
  424. Register x = v.r;
  425. int y = v.i;
  426. setRegister(Register.A, pred(getRegister(x), y));
  427. }
  428.  
  429. void run(Instruction[] prog) {
  430. if (prog.empty) {
  431. //writeln("No more instruction");
  432. }
  433. else {
  434. Instruction inst = prog[0];
  435. Instruction[] rest = prog[1 .. $];
  436.  
  437. final switch (inst.type) {
  438. case InstructionType.Func:
  439. Func func = cast(Func)inst;
  440. int id = func.id;
  441. Instruction[] proc = func.proc;
  442. saveFunction(id, proc);
  443. run(rest);
  444. break;
  445. case InstructionType.CallF:
  446. CallF callf = cast(CallF)inst;
  447. int id = callf.id;
  448. getFunction(id).run;
  449. run(rest);
  450. break;
  451. case InstructionType.CallFA:
  452. CallFA callfa = cast(CallFA)inst;
  453. int id = callfa.id;
  454. int[] args = callfa.args;
  455. setArgs(args);
  456. getFunction(id).run;
  457. run(rest);
  458. break;
  459. case InstructionType.CallFAR:
  460. CallFAR callfar = cast(CallFAR)inst;
  461. int id = callfar.id;
  462. Register[] args = callfar.args;
  463. args.map!(x => getRegister(x)).array.setArgs;
  464. getFunction(id).run;
  465. run(rest);
  466. break;
  467. case InstructionType.HLT:
  468. writeln("execution stopped");
  469. break;
  470. case InstructionType.Print:
  471. Print print = cast(Print)inst;
  472. Register r = print.r;
  473. writefln("%s : %d", r, getRegister(r));
  474. run(rest);
  475. break;
  476. case InstructionType.Eq:
  477. compOpR2!(Eq, ((int x, int y) => x == y))(inst);
  478. run(rest);
  479. break;
  480. case InstructionType.Neq:
  481. compOpR2!(Neq, ((int x, int y) => x != y))(inst);
  482. run(rest);
  483. break;
  484. case InstructionType.Leq:
  485. compOpR2!(Leq, ((int x, int y) => x <= y))(inst);
  486. run(rest);
  487. break;
  488. case InstructionType.Geq:
  489. compOpR2!(Geq, ((int x, int y) => x >= y))(inst);
  490. run(rest);
  491. break;
  492. case InstructionType.Lt:
  493. compOpR2!(Lt, ((int x, int y) => x < y))(inst);
  494. run(rest);
  495. break;
  496. case InstructionType.Gt:
  497. compOpR2!(Lt, ((int x, int y) => x > y))(inst);
  498. run(rest);
  499. break;
  500. case InstructionType.EqI:
  501. compOpRI!(EqI, ((int x, int y) => x == y))(inst);
  502. run(rest);
  503. break;
  504. case InstructionType.NeqI:
  505. compOpRI!(NeqI, ((int x, int y) => x != y))(inst);
  506. run(rest);
  507. break;
  508. case InstructionType.LeqI:
  509. compOpRI!(LeqI, ((int x, int y) => x <= y))(inst);
  510. run(rest);
  511. break;
  512. case InstructionType.GeqI:
  513. compOpRI!(GeqI, ((int x, int y) => x >= y))(inst);
  514. run(rest);
  515. break;
  516. case InstructionType.LtI:
  517. compOpRI!(LtI, ((int x, int y) => x < y))(inst);
  518. run(rest);
  519. break;
  520. case InstructionType.GtI:
  521. compOpRI!(GtI, ((int x, int y) => x > y))(inst);
  522. run(rest);
  523. break;
  524. case InstructionType.If:
  525. If _if = cast(If)inst;
  526. Register r = _if.r;
  527. Instruction[][] insts = _if.insts;
  528.  
  529. if (getRegister(r) == 1) {
  530. run(insts[0]);
  531. }
  532. else if (insts.length == 2) {
  533. run(insts[1]);
  534. }
  535. run(rest);
  536. break;
  537. case InstructionType.RetR:
  538. RetR retr = cast(RetR)inst;
  539. Register x = retr.r;
  540. setRegister(Register.A, (getRegister(x)));
  541. run(rest);
  542. break;
  543. case InstructionType.RetI:
  544. RetI reti = cast(RetI)inst;
  545. int x = reti.i;
  546. setRegister(Register.A, x);
  547. run(rest);
  548. break;
  549. case InstructionType.AddR:
  550. arithmaticOpR2!(AddR, ((int x, int y) => x + y))(inst);
  551. run(rest);
  552. break;
  553. case InstructionType.AddI:
  554. arithmaticOpRI!(AddI, ((int x, int y) => x + y))(inst);
  555. run(rest);
  556. break;
  557. case InstructionType.SubR:
  558. arithmaticOpR2!(SubR, ((int x, int y) => x - y))(inst);
  559. run(rest);
  560. break;
  561. case InstructionType.SubI:
  562. arithmaticOpRI!(SubI, ((int x, int y) => x - y))(inst);
  563. run(rest);
  564. break;
  565. case InstructionType.MulR:
  566. arithmaticOpR2!(MulR, ((int x, int y) => x * y))(inst);
  567. run(rest);
  568. break;
  569. case InstructionType.MulI:
  570. arithmaticOpRI!(MulI, ((int x, int y) => x * y))(inst);
  571. run(rest);
  572. break;
  573. case InstructionType.MovR:
  574. MovR movr = cast(MovR)inst;
  575. Register x = movr.r1, y = movr.r2;
  576. setRegister(x, getRegister(y));
  577. run(rest);
  578. break;
  579. case InstructionType.MovI:
  580. MovI movi = cast(MovI)inst;
  581. Register x = movi.r;
  582. int y = movi.i;
  583. setRegister(x, y);
  584. run(rest);
  585. break;
  586. case InstructionType.PopTo:
  587. PopTo popto = cast(PopTo)inst;
  588. Register r = popto.r;
  589. popTo(stack, r);
  590. run(rest);
  591. break;
  592. case InstructionType.PushR:
  593. PushR pr = cast(PushR)inst;
  594. stack.push(getRegister(pr.r));
  595. run(rest);
  596. break;
  597. case InstructionType.PushI:
  598. PushI pi = cast(PushI)inst;
  599. stack.push(pi.i);
  600. run(rest);
  601. break;
  602. }
  603. }
  604. }
  605.  
  606. void main() {
  607. /*
  608. Func#1 is same as
  609. let rec fact n =
  610. if n = 0 then 1
  611. else
  612. let m = n - 1 in
  613. let k = fact m in
  614. return n * k;;
  615.  
  616. [
  617. func(1, [
  618. eqi(F, 0),
  619. _if(B, [[
  620. reti(1)
  621. ], [
  622. subi(F, 1),
  623. movr(D, A),
  624. pushr(F),
  625. callfar(1, [D]),
  626. popto(E),
  627. mulr(E, A),
  628. retr(A)]
  629. ])
  630. ]),
  631. callfa(1, [10]),
  632. print(A)
  633. ]
  634. */
  635. with (Register) {
  636. Instruction[] program = [func(1, [eqi(F, 0), _if(B, [[reti(1)], [subi(F,
  637. 1), movr(D, A), pushr(F), callfar(1, [D]), popto(E), mulr(E, A), retr(A)]])]),
  638. callfa(1, [10]), print(A)];
  639. run(program);
  640. }
  641. }
Add Comment
Please, Sign In to add comment