From 060a955ff58efde6cb51ab18eaed8f479e2550f3 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Mon, 24 Jul 2017 22:33:46 +0300 Subject: [PATCH] =?utf8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?utf8?q?=D1=8B=20=D0=BC=D0=BD=D0=BE=D0=B3=D0=BE=D0=BC=D0=B5=D1=80=D0=BD?= =?utf8?q?=D1=8B=D0=B5=20=D0=BC=D0=B0=D1=81=D1=81=D0=B8=D0=B2=D1=8B=20?= =?utf8?q?=D0=B8=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=87=D0=B5=D1=81=D0=BA?= =?utf8?q?=D0=B0=D1=8F=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B0?= =?utf8?q?=20=D0=B8=D0=BD=D0=B4=D0=B5=D0=BA=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- notes | 6 ++-- oberon.c | 96 ++++++++++++++++++++++++++++++++++++++++++-------- test.c | 10 ++---- test/Test | Bin 10344 -> 10336 bytes test/Test.Mod | 12 +++---- test/Test.c | 16 +++++---- 6 files changed, 102 insertions(+), 38 deletions(-) diff --git a/notes b/notes index 0dd194e..c7324d2 100644 --- a/notes +++ b/notes @@ -1,13 +1,13 @@ -- хреновая проверка типов-указателей +- не реализованы var-параметры в генераторе + - нету процедуры NEW - не реализовано расширение типа record -- не реализована краткая форма многомерных массивов и краткой формы доступа к ним (* [1, 2, 3] - компилится, но вычисляется только первый аргумент *) +- нету открытых массивов - не реализованы локальные объявления в процедурах - не работает присваивание к переменным-процедурам. - не понятен результат присваивания статических структур (* reca := recb; *) - не понятен результат присваивания статических массивов (* arr1 := arr2; *) -- не реализованы var-параметры в генераторе - не реализованы процедуры "наперёд" - нету типа set diff --git a/oberon.c b/oberon.c index dfed94a..b7ffd0e 100644 --- a/oberon.c +++ b/oberon.c @@ -572,6 +572,7 @@ static oberon_expr_t * oberon_expr(oberon_context_t * ctx); static void oberon_assert_token(oberon_context_t * ctx, int token); static char * oberon_assert_ident(oberon_context_t * ctx); static void oberon_type(oberon_context_t * ctx, oberon_type_t ** type); +static oberon_item_t * oberon_const_expr(oberon_context_t * ctx); static oberon_expr_t * oberon_new_operator(int op, oberon_type_t * result, oberon_expr_t * left, oberon_expr_t * right) @@ -638,7 +639,7 @@ oberon_make_unary_op(oberon_context_t * ctx, int token, oberon_expr_t * a) } static void -oberon_expr_list(oberon_context_t * ctx, int * num_expr, oberon_expr_t ** first) +oberon_expr_list(oberon_context_t * ctx, int * num_expr, oberon_expr_t ** first, int const_expr) { oberon_expr_t * last; @@ -648,7 +649,16 @@ oberon_expr_list(oberon_context_t * ctx, int * num_expr, oberon_expr_t ** first) { oberon_assert_token(ctx, COMMA); oberon_expr_t * current; - current = oberon_expr(ctx); + + if(const_expr) + { + current = (oberon_expr_t *) oberon_const_expr(ctx); + } + else + { + current = oberon_expr(ctx); + } + last -> next = current; last = current; *num_expr += 1; @@ -663,7 +673,6 @@ oberon_autocast_to(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * oberon_error(ctx, "incompatible types"); } - if(pref -> class == OBERON_TYPE_INTEGER) { if(expr -> result -> class > pref -> class) @@ -679,6 +688,16 @@ oberon_autocast_to(oberon_context_t * ctx, oberon_expr_t * expr, oberon_type_t * oberon_error(ctx, "incompatible record types"); } } + else if(pref -> class == OBERON_TYPE_POINTER) + { + if(expr -> result -> base != pref -> base) + { + if(expr -> result -> base -> class != OBERON_TYPE_VOID) + { + oberon_error(ctx, "incompatible pointer types"); + } + } + } // TODO cast @@ -754,7 +773,7 @@ oberno_make_dereferencing(oberon_context_t * ctx, oberon_expr_t * expr) } static oberon_expr_t * -oberon_make_array_selector(oberon_context_t * ctx, oberon_expr_t * desig, int num_indexes, oberon_expr_t * indexes) +oberon_make_array_selector(oberon_context_t * ctx, oberon_expr_t * desig, oberon_expr_t * index) { if(desig -> result -> class == OBERON_TYPE_POINTER) { @@ -773,11 +792,30 @@ oberon_make_array_selector(oberon_context_t * ctx, oberon_expr_t * desig, int nu // TODO check ranges + printf("oberon_make_array_selector: index class %i\n", index -> result -> class); + if(index -> result -> class != OBERON_TYPE_INTEGER) + { + oberon_error(ctx, "index must be integer"); + } + + if(index -> is_item) + { + if(index -> item.mode == MODE_INTEGER) + { + int arr_size = desig -> result -> size; + int index_int = index -> item.integer; + if(index_int < 0 || index_int > arr_size - 1) + { + oberon_error(ctx, "not in range (dimension size 0..%i)", arr_size - 1); + } + } + } + oberon_expr_t * selector; selector = oberon_new_item(MODE_INDEX, base); selector -> item.parent = (oberon_item_t *) desig; - selector -> item.num_args = num_indexes; - selector -> item.args = indexes; + selector -> item.num_args = 1; + selector -> item.args = index; return selector; } @@ -858,9 +896,14 @@ oberon_designator(oberon_context_t * ctx) oberon_assert_token(ctx, LBRACE); int num_indexes = 0; oberon_expr_t * indexes = NULL; - oberon_expr_list(ctx, &num_indexes, &indexes); + oberon_expr_list(ctx, &num_indexes, &indexes, 0); oberon_assert_token(ctx, RBRACE); - expr = oberon_make_array_selector(ctx, expr, num_indexes, indexes); + + for(int i = 0; i < num_indexes; i++) + { + expr = oberon_make_array_selector(ctx, expr, indexes); + indexes = indexes -> next; + } break; case UPARROW: oberon_assert_token(ctx, UPARROW); @@ -893,7 +936,7 @@ oberon_opt_proc_parens(oberon_context_t * ctx, oberon_expr_t * expr) if(ISEXPR(ctx -> token)) { - oberon_expr_list(ctx, &num_args, &arguments); + oberon_expr_list(ctx, &num_args, &arguments, 0); } expr -> result = expr -> item.var -> type -> base; @@ -1423,9 +1466,14 @@ oberon_const_decl(oberon_context_t * ctx) } static void -oberon_make_array_type(oberon_context_t * ctx, oberon_item_t * size, oberon_type_t * base, oberon_type_t ** type) +oberon_make_array_type(oberon_context_t * ctx, oberon_expr_t * size, oberon_type_t * base, oberon_type_t ** type) { - if(size -> mode != MODE_INTEGER) + if(size -> is_item == 0) + { + oberon_error(ctx, "requires constant"); + } + + if(size -> item.mode != MODE_INTEGER) { oberon_error(ctx, "requires integer constant"); } @@ -1433,7 +1481,7 @@ oberon_make_array_type(oberon_context_t * ctx, oberon_item_t * size, oberon_type oberon_type_t * arr; arr = *type; arr -> class = OBERON_TYPE_ARRAY; - arr -> size = size -> integer; + arr -> size = size -> item.integer; arr -> base = base; } @@ -1484,6 +1532,23 @@ static void oberon_opt_formal_pars(oberon_context_t * ctx, oberon_type_t ** type * Правило граматики "type". Указатель type должен указывать на существующий объект! */ +static void +oberon_make_multiarray(oberon_context_t * ctx, oberon_expr_t * sizes, oberon_type_t * base, oberon_type_t ** type) +{ + if(sizes == NULL) + { + *type = base; + return; + } + + oberon_type_t * dim; + dim = oberon_new_type_ptr(OBERON_TYPE_VOID); + + oberon_make_multiarray(ctx, sizes -> next, base, &dim); + + oberon_make_array_type(ctx, sizes, dim, type); +} + static void oberon_type(oberon_context_t * ctx, oberon_type_t ** type) { @@ -1495,8 +1560,9 @@ oberon_type(oberon_context_t * ctx, oberon_type_t ** type) { oberon_assert_token(ctx, ARRAY); - oberon_item_t * size; - size = oberon_const_expr(ctx); + int num_sizes = 0; + oberon_expr_t * sizes; + oberon_expr_list(ctx, &num_sizes, &sizes, 1); oberon_assert_token(ctx, OF); @@ -1504,7 +1570,7 @@ oberon_type(oberon_context_t * ctx, oberon_type_t ** type) base = oberon_new_type_ptr(OBERON_TYPE_VOID); oberon_type(ctx, &base); - oberon_make_array_type(ctx, size, base, type); + oberon_make_multiarray(ctx, sizes, base, type); } else if(ctx -> token == RECORD) { diff --git a/test.c b/test.c index b934af8..d8f1083 100644 --- a/test.c +++ b/test.c @@ -5,15 +5,11 @@ static const char source[] = "MODULE Test;" "TYPE" - " MyRec = POINTER TO MyRecDesc;" - " MyRecDesc = RECORD" - " a : INTEGER;" - " END;" + " Matrix = ARRAY 3, 4 OF INTEGER;" "VAR" - " r : MyRec;" + " m : Matrix;" "BEGIN;" - " r := NIL;" - " r.a := 1;" + " m[2, 3] := 0;" "END Test." ; diff --git a/test/Test b/test/Test index 09dbea89f6a56f7f03fd224992382247908ac664..de23f9b639cfb000e82fcdc28851179dcb4907da 100755 GIT binary patch delta 3214 zcmZt|3vgUj_1^dP^WNsOzif6>L$cX?3pQ&Kl9UW>cl!yOPAprR;E1%@G)sZA@RHj1`ZbfTD=D0IryVZgDh=iK*R$}BxQ z_x$g9=iYnH-n$fCh^Bqcs5Qh0G|bq-`0DT5-n0oFd($?4sa749G${>E{#Dl@Rg(^> z+LS{o{D5C-Ts`plf?J=wXY;>jw>-bie&##ZZK)|4J#%qz92Oi0X8fF)LMrL* zDabzuT=w#9grAXpJT1gHbjv}W5`2Te8wIWwc$9GRdlZ6s*{~yq+zt3CvJU2B=`8&V zx<1>#4D~LS!zL^t>Hzqgcxe8HCEMB-1f3 zpBM5*l4*I%GeT}5nHIWyLdf+bQ|OxtU=+v&h^jCdgc?f=PQGQT*&b_R`IabxuRyaniF4MnkM0JEu6Y8FYSZhs1FoX z;QTM+7fvJXK>BTr{6nNCVY{uF_d&`QG*A35lbM89Y~>CAM6Xh`vT(lRDQQ!l<-S}i z9ab@pJvc5K*%)?dYRaASjs#;llQusd7Qt03*z!vP)B*(br$JzJX`Uuxcf!{EU6{fP z`K5dw&gE~AE;6v$OPn+2kno|hAxOg=_8^Zz++NCCVBX`#&+U1};R~O!goMK%b$VH+ z@9ETH)$D~jt8uikmQM zNK&lZkdq^br0NZX6*Kj_$z+ZXCYWTh?jZX$veb7Gmdxe&1xd0lpd?cZN{x>Z=9VK! zlH%V*YC0%X$^;VmC&X_ZAojP!w$m0%Cex!t6w@pcvto%Ok=1d+#}V<|Un92C+5ZKH zvIddFJJ0#5gG=hByufTvzxoJnG*531cqaO+UL9T2$OhnR4;7Qk`3Q z7B0K*hV=!$=$66JfoS645q9@zqN{CW)6n3^P=7Dm+dtHuU>&_9iLU6qy*-Jchc%&F zBfHt?;7EMmVDBD(PhYog6Mk@@;0RQBzJO(Y%;Oc+>X8)|!>aY-4LR@e$Tl_uywF=` z^aCYsfQ;R8LN8uJM^t8cEQ-bIX}`&>ChT@LmVMg^y@MI|J;gCVW=?h%@BhNDVOy1X zJ+hAt!*=h5wlTdk3`Y+#5`O$dmcB;UU(M35M?J?Yd>9_`1-T!N`R>||)r49sJ%Jhf z5mNFo>WR9G;3XXNE#usbGk*p3pNp|e zWKF&$GReaR35m>m_5A;e^kxsPZ|eTW8}l~Z{~GGapRUo5LPqz`{yQ+?2D%snZ?Ut; zfjs4(J+~N~#a>=RSluP!;DZjji+^4y+HW^oY0-h&x;q*g;FGr;gja8Q(51c8LLuXY zR(Crzmh7JTZplGDRpk$GJ^^iIL1&*SBvKWx7UbsPZ(cVXEh~1m=+{h(SzAj0&Y^!y z*T!`1r$7w^)wHfnLpab3YXc6ts}2TgRile1;8dX5Y4q+1y{0EYEf20d)uZ}_7J#<$ zpv`!l;yw6ed6Ug(-!TcFHdeH9?AlaiP&Fzg2B#{UVY! delta 3347 zcmZu!4Nz3q6~6bq{dsSJ{Q;J@OB7ZptVU%62B~Q+yETwU1`R0?%QOc3!9t5bWr?IU zF4Q!2%}^n?<2Xs2l8iPsV>?>S4<^M$Q>nH|i8HMo(`KyEncYrxXqy_EiEhuidmka& zUgmx0obR0bf9~GPm4baYDLdcgg)fzUsHWHIcY=w+xYX_$Yi9`1Ztnl$e4la!&ZN z*|-#-y^P8Mx*1TTB^(cP+=a;6WDgB+Tj#i*d>oMi$*L8=j=~^lXm?=E z#FZqJlE0yid61aq_Eoeam{^GzCoUs_36nU+?TcvR=o4eyzJRtF?GbLDK^teA807XT zv~gyMUT*&qZ3XQ%Zoh)Iigp9HUjjSQfw`Or0#SaWF8bbMdi1Kk``S!HQ{7a|2^+0X zO^&H3rruRxR_0JvocUubvnYW`&8!|hGl8q553jxe zgNYx$lT41BKZ~KTInL;lpX$;68GX2U=9wB${}`Q$e+@$78vyj^6dz@L42|JRTv%u) z54I)65AYy!6dQgN^w2miaELp{A&MPU@*)>+V@u{QK@gqC#!MK6V#LrwL=CF@K+SghgYC>ul3 z+jY@f^-FMqif*2~Eyw+=O#PPk+Na4R);MRk@?1Lm(oOpGnG z6|b0rC_i{f$nJbvT9akjlxfBMSODJ^_}&Hod608{>FpDJwi}Xd47MIiuflBhf+9SH zSd8;x{7@L@B-h3sv_D1HF-wy;@QzvpEV}Gv*+#iCKyz##T83bc}U63Tc@A z)t$qx*tR_D^fZ==-{h4-)(ZKEkXwa(T*#+|+%M!$g?vrObJiexkGff}^M3VZF`F4+ zw8$aYRTCeKLUFG%PXkN~FpGL~0oY5y4a@(#pM@Qucw652F6yHdIfcS|33)nRcL1OuqnO zRxF($WEIF(dw5Z>O$%5%LHcpugEt?B9R>*;DITf2HThDlRkziu?qJtNa5pdjc2A?R>&A+s77OeZrMg=m@7}C zvn-V7UXe+hBGGWTMv+MtF&-BNhf>B%lzqpWW0r}7_=M&p%Y^149jLM2+a zA@Z82dxV9&e($fiF_iB;r+{}h-_`G+P^RN!K zAlD4YfJC4q53c?;gW_@#@YyhXyr-~;M;dt+cpuS7Z(4jgk0m2DDE$o!Eef~}n1Xx;2gI_x&xU{vi+dz&PED_rO#(Y6*fGKS7%d8@ zF~P!JQ&g30+(0uT1}>)W7nP~AmQ**hY`mz-WgKRwHPw8K(c-||{|VEA{VEF;2W-Y` z7%si<7O%7!yXdpAQ(zjY4F4j00%nKU;||-2`@T?1;dBp`1XLqydf9kMmCIP=LGjSN z2Rhf7r_@IW*{afNdXha+TCH9a-Xm