OILS / demo / old / arith_demo.cc View on Github | oilshell.org

134 lines, 97 significant
1#include <string>
2#include <stdio.h>
3#include <stdlib.h>
4
5#include "arith.asdl.h"
6
7void PrintExpr(const uint32_t* base, const arith_expr_t& e, int indent) {
8 for (int i = 0; i < indent; ++i) {
9 putchar('\t');
10 }
11 printf("t%hhu ", e.tag());
12
13 switch (e.tag()) {
14 case arith_expr_e::Const: {
15 auto& e2 = static_cast<const Const&>(e);
16 printf("CONST %d\n", e2.i());
17 break;
18 }
19 case arith_expr_e::ArithVar: {
20 auto& e2 = static_cast<const ArithVar&>(e);
21 printf("VAR %s\n", e2.name(base));
22 break;
23 }
24 case arith_expr_e::ArithUnary: {
25 auto& e2 = static_cast<const ArithUnary&>(e);
26 printf("UNARY\n");
27 break;
28 }
29 case arith_expr_e::ArithBinary: {
30 auto& e2 = static_cast<const ArithBinary&>(e);
31 printf("BINARY\n");
32 for (int i = 0; i < indent+1; ++i) {
33 putchar('\t');
34 }
35 // TODO:
36 // char* DebugString(op_id_e op_id)
37 //printf("INT %d\n", e2.Int(1));
38 printf("%hhu\n", e2.op_id());
39
40 PrintExpr(base, e2.left(base), indent+1);
41 PrintExpr(base, e2.right(base), indent+1);
42 break;
43 }
44 case arith_expr_e::FuncCall: {
45 auto& e2 = static_cast<const FuncCall&>(e);
46 printf("FUNC CALL\n");
47 for (int i = 0; i < indent+1; ++i) {
48 putchar('\t');
49 }
50 printf("name %s\n", e2.name(base));
51 for (int i = 0; i < e2.args_size(base); ++i) {
52 PrintExpr(base, e2.args(base, i), indent+1);
53 }
54 break;
55 }
56 case arith_expr_e::Index: {
57 auto& e2 = static_cast<const Index&>(e);
58 printf("INDEX\n");
59 PrintExpr(base, e2.a(base), indent+1);
60 PrintExpr(base, e2.index(base), indent+1);
61 break;
62 }
63 case arith_expr_e::Slice: {
64 auto& e2 = static_cast<const Slice&>(e);
65 printf("SLICE\n");
66 const arith_expr_t* begin = e2.begin(base);
67 const arith_expr_t* end = e2.end(base);
68 const arith_expr_t* stride = e2.stride(base);
69 PrintExpr(base, e2.a(base), indent+1);
70 if (begin) PrintExpr(base, *begin, indent+1);
71 if (end) PrintExpr(base, *end, indent+1);
72 if (stride) {
73 PrintExpr(base, *stride, indent+1);
74 } else {
75 for (int i = 0; i < indent+1; ++i) {
76 putchar('\t');
77 }
78 printf("stride: %p\n", stride);
79 }
80 break;
81 }
82 default:
83 printf("OTHER\n");
84 break;
85 }
86}
87
88// Returns the root ref, or -1 for invalid
89int GetRootRef(uint8_t* image) {
90 if (image[0] != 'O') return -1;
91 if (image[1] != 'H') return -1;
92 if (image[2] != 'P') return -1;
93 if (image[3] != 1) return -1; // version 1
94 if (image[4] != 4) return -1; // alignment 4
95
96 return image[5] + (image[6] << 8) + (image[7] << 16);
97}
98
99int main(int argc, char **argv) {
100 if (argc == 0) {
101 printf("Expected filename\n");
102 return 1;
103 }
104 FILE *f = fopen(argv[1], "rb");
105 if (!f) {
106 printf("Error opening %s", argv[1]);
107 return 1;
108 }
109 fseek(f, 0, SEEK_END);
110 size_t num_bytes = ftell(f);
111 fseek(f, 0, SEEK_SET); //same as rewind(f);
112
113 uint8_t* image = static_cast<uint8_t*>(malloc(num_bytes + 1));
114 fread(image, num_bytes, 1, f);
115 fclose(f);
116
117 image[num_bytes] = 0;
118 printf("Read %zu bytes\n", num_bytes);
119
120 int root_ref = GetRootRef(image);
121 if (root_ref == -1) {
122 printf("Invalid image\n");
123 return 1;
124 }
125 // Hm we could make the root ref be a BYTE offset?
126 int alignment = 4;
127 printf("alignment: %d root: %d\n", alignment, root_ref);
128
129 auto base = reinterpret_cast<uint32_t*>(image);
130
131 size_t offset = alignment * root_ref + 0;
132 auto expr = reinterpret_cast<arith_expr_t*>(image + offset);
133 PrintExpr(base, *expr, 0);
134}