🐐 Array slicing
This commit is contained in:
@@ -121,6 +121,14 @@ Individual elements can be accessed by index using square brackets. Indexing is
|
||||
> I
|
||||
```
|
||||
|
||||
A sub-array can be extracted with `VSQVE` inside the index brackets. Both bounds are inclusive and 1-based:
|
||||
|
||||

|
||||
|
||||
```
|
||||
> [XX, XXX, XL]
|
||||
```
|
||||
|
||||
### Dicts (TABVLA)
|
||||
|
||||
Dicts are key-value maps created with the `TABVLA` keyword and curly braces:
|
||||
|
||||
@@ -847,6 +847,49 @@ class ArrayIndex(Node):
|
||||
return vtable, lst[i - 1]
|
||||
|
||||
|
||||
def _to_index_int(val):
|
||||
if isinstance(val, ValInt):
|
||||
return val.value()
|
||||
if isinstance(val, ValFrac) and val.value().denominator == 1:
|
||||
return val.value().numerator
|
||||
raise CentvrionError("Array index must be a number")
|
||||
|
||||
|
||||
class ArraySlice(Node):
|
||||
def __init__(self, array, from_index, to_index) -> None:
|
||||
self.array = array
|
||||
self.from_index = from_index
|
||||
self.to_index = to_index
|
||||
|
||||
def __eq__(self, other):
|
||||
return (type(self) == type(other)
|
||||
and self.array == other.array
|
||||
and self.from_index == other.from_index
|
||||
and self.to_index == other.to_index)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"ArraySlice({self.array!r}, {self.from_index!r}, {self.to_index!r})"
|
||||
|
||||
def print(self):
|
||||
return f"{self.array.print()}[{self.from_index.print()} VSQVE {self.to_index.print()}]"
|
||||
|
||||
def _eval(self, vtable):
|
||||
vtable, array = self.array.eval(vtable)
|
||||
vtable, from_val = self.from_index.eval(vtable)
|
||||
vtable, to_val = self.to_index.eval(vtable)
|
||||
if not isinstance(array, ValList):
|
||||
raise CentvrionError("Cannot slice a non-array value")
|
||||
from_int = _to_index_int(from_val)
|
||||
to_int = _to_index_int(to_val)
|
||||
lst = array.value()
|
||||
if from_int < 1 or to_int > len(lst) or from_int > to_int:
|
||||
raise CentvrionError(
|
||||
f"Slice [{from_int} VSQVE {to_int}] out of range"
|
||||
f" for array of length {len(lst)}"
|
||||
)
|
||||
return vtable, ValList(lst[from_int - 1 : to_int])
|
||||
|
||||
|
||||
class SiStatement(Node):
|
||||
def __init__(self, test, statements, else_part) -> None:
|
||||
self.test = test
|
||||
|
||||
@@ -2,7 +2,7 @@ from centvrion.errors import CentvrionError
|
||||
from centvrion.ast_nodes import (
|
||||
String, InterpolatedString, Numeral, Fractio, Bool, Nullus, ID,
|
||||
BinOp, UnaryMinus, UnaryNot,
|
||||
ArrayIndex, DataArray, DataRangeArray, DataDict,
|
||||
ArrayIndex, ArraySlice, DataArray, DataRangeArray, DataDict,
|
||||
BuiltIn, Invoca, Fvnctio,
|
||||
num_to_int, frac_to_fraction,
|
||||
)
|
||||
@@ -120,6 +120,15 @@ def emit_expr(node, ctx):
|
||||
tmp = ctx.fresh_tmp()
|
||||
return arr_lines + idx_lines + [f"CentValue {tmp} = cent_list_index({arr_var}, {idx_var});"], tmp
|
||||
|
||||
if isinstance(node, ArraySlice):
|
||||
arr_lines, arr_var = emit_expr(node.array, ctx)
|
||||
lo_lines, lo_var = emit_expr(node.from_index, ctx)
|
||||
hi_lines, hi_var = emit_expr(node.to_index, ctx)
|
||||
tmp = ctx.fresh_tmp()
|
||||
return arr_lines + lo_lines + hi_lines + [
|
||||
f"CentValue {tmp} = cent_list_slice({arr_var}, {lo_var}, {hi_var});"
|
||||
], tmp
|
||||
|
||||
if isinstance(node, DataArray):
|
||||
lines = []
|
||||
tmp = ctx.fresh_tmp()
|
||||
|
||||
@@ -735,6 +735,22 @@ CentValue cent_list_index(CentValue lst, CentValue idx) {
|
||||
return lst.lval.items[i - 1];
|
||||
}
|
||||
|
||||
CentValue cent_list_slice(CentValue lst, CentValue lo, CentValue hi) {
|
||||
if (lst.type != CENT_LIST)
|
||||
cent_type_error("slice requires a list");
|
||||
if (lo.type != CENT_INT || hi.type != CENT_INT)
|
||||
cent_type_error("slice indices must be integers");
|
||||
long from = lo.ival;
|
||||
long to = hi.ival;
|
||||
if (from < 1 || to > lst.lval.len || from > to)
|
||||
cent_runtime_error("slice out of range");
|
||||
int len = (int)(to - from + 1);
|
||||
CentValue result = cent_list_new(len);
|
||||
for (long j = from; j <= to; j++)
|
||||
cent_list_push(&result, lst.lval.items[j - 1]);
|
||||
return result;
|
||||
}
|
||||
|
||||
void cent_list_index_set(CentValue *lst, CentValue idx, CentValue v) {
|
||||
if (lst->type == CENT_DICT) {
|
||||
cent_dict_set(lst, idx, v);
|
||||
|
||||
@@ -234,6 +234,7 @@ void cent_adivnge(CentValue path, CentValue content); /* ADIVNGE */
|
||||
CentValue cent_list_new(int cap);
|
||||
void cent_list_push(CentValue *lst, CentValue v);
|
||||
CentValue cent_list_index(CentValue lst, CentValue idx); /* 1-based */
|
||||
CentValue cent_list_slice(CentValue lst, CentValue lo, CentValue hi); /* 1-based, inclusive */
|
||||
void cent_list_index_set(CentValue *lst, CentValue idx, CentValue v);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
@@ -326,6 +326,10 @@ class Parser():
|
||||
def array_index(tokens):
|
||||
return ast_nodes.ArrayIndex(tokens[0], tokens[2])
|
||||
|
||||
@self.pg.production('expression : expression SYMBOL_LBRACKET expression KEYWORD_VSQVE expression SYMBOL_RBRACKET', precedence='INDEX')
|
||||
def array_slice(tokens):
|
||||
return ast_nodes.ArraySlice(tokens[0], tokens[2], tokens[4])
|
||||
|
||||
# ids
|
||||
@self.pg.production('ids : SYMBOL_LPARENS id_list')
|
||||
def ids(tokens):
|
||||
|
||||
2
language/main.aux
Normal file
2
language/main.aux
Normal file
@@ -0,0 +1,2 @@
|
||||
\relax
|
||||
\gdef \@abspage@last{2}
|
||||
269
language/main.log
Normal file
269
language/main.log
Normal file
@@ -0,0 +1,269 @@
|
||||
This is XeTeX, Version 3.141592653-2.6-0.999998 (TeX Live 2026/Arch Linux) (preloaded format=xelatex 2026.4.8) 21 APR 2026 22:51
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
%&-line parsing enabled.
|
||||
**main.tex
|
||||
(./main.tex
|
||||
LaTeX2e <2025-11-01>
|
||||
L3 programming layer <2026-01-19>
|
||||
(/usr/share/texmf-dist/tex/latex/base/article.cls
|
||||
Document Class: article 2025/01/22 v1.4n Standard LaTeX document class
|
||||
(/usr/share/texmf-dist/tex/latex/base/size10.clo
|
||||
File: size10.clo 2025/01/22 v1.4n Standard LaTeX file (size option)
|
||||
)
|
||||
\c@part=\count271
|
||||
\c@section=\count272
|
||||
\c@subsection=\count273
|
||||
\c@subsubsection=\count274
|
||||
\c@paragraph=\count275
|
||||
\c@subparagraph=\count276
|
||||
\c@figure=\count277
|
||||
\c@table=\count278
|
||||
\abovecaptionskip=\skip49
|
||||
\belowcaptionskip=\skip50
|
||||
\bibindent=\dimen148
|
||||
)
|
||||
(/usr/share/texmf-dist/tex/latex/geometry/geometry.sty
|
||||
Package: geometry 2020/01/02 v5.9 Page Geometry
|
||||
|
||||
(/usr/share/texmf-dist/tex/latex/graphics/keyval.sty
|
||||
Package: keyval 2022/05/29 v1.15 key=value parser (DPC)
|
||||
\KV@toks@=\toks17
|
||||
)
|
||||
(/usr/share/texmf-dist/tex/generic/iftex/ifvtex.sty
|
||||
Package: ifvtex 2019/10/25 v1.7 ifvtex legacy package. Use iftex instead.
|
||||
|
||||
(/usr/share/texmf-dist/tex/generic/iftex/iftex.sty
|
||||
Package: iftex 2024/12/12 v1.0g TeX engine tests
|
||||
))
|
||||
\Gm@cnth=\count279
|
||||
\Gm@cntv=\count280
|
||||
\c@Gm@tempcnt=\count281
|
||||
\Gm@bindingoffset=\dimen149
|
||||
\Gm@wd@mp=\dimen150
|
||||
\Gm@odd@mp=\dimen151
|
||||
\Gm@even@mp=\dimen152
|
||||
\Gm@layoutwidth=\dimen153
|
||||
\Gm@layoutheight=\dimen154
|
||||
\Gm@layouthoffset=\dimen155
|
||||
\Gm@layoutvoffset=\dimen156
|
||||
\Gm@dimlist=\toks18
|
||||
)
|
||||
(/usr/share/texmf-dist/tex/latex/fontspec/fontspec.sty
|
||||
(/usr/share/texmf-dist/tex/latex/l3packages/xparse/xparse.sty
|
||||
(/usr/share/texmf-dist/tex/latex/l3kernel/expl3.sty
|
||||
Package: expl3 2026-01-19 L3 programming layer (loader)
|
||||
|
||||
(/usr/share/texmf-dist/tex/latex/l3backend/l3backend-xetex.def
|
||||
File: l3backend-xetex.def 2025-10-09 L3 backend support: XeTeX
|
||||
\g__graphics_track_int=\count282
|
||||
\g__pdfannot_backend_int=\count283
|
||||
\g__pdfannot_backend_link_int=\count284
|
||||
))
|
||||
Package: xparse 2025-10-09 L3 Experimental document command parser
|
||||
)
|
||||
Package: fontspec 2025/09/29 v2.9g Font selection for XeLaTeX and LuaLaTeX
|
||||
|
||||
(/usr/share/texmf-dist/tex/latex/fontspec/fontspec-xetex.sty
|
||||
Package: fontspec-xetex 2025/09/29 v2.9g Font selection for XeLaTeX and LuaLaTe
|
||||
X
|
||||
\l__fontspec_script_int=\count285
|
||||
\l__fontspec_language_int=\count286
|
||||
\l__fontspec_strnum_int=\count287
|
||||
\l__fontspec_tmp_int=\count288
|
||||
\l__fontspec_tmpa_int=\count289
|
||||
\l__fontspec_tmpb_int=\count290
|
||||
\l__fontspec_tmpc_int=\count291
|
||||
\l__fontspec_em_int=\count292
|
||||
\l__fontspec_emdef_int=\count293
|
||||
\l__fontspec_strong_int=\count294
|
||||
\l__fontspec_strongdef_int=\count295
|
||||
\l__fontspec_tmpa_dim=\dimen157
|
||||
\l__fontspec_tmpb_dim=\dimen158
|
||||
\l__fontspec_tmpc_dim=\dimen159
|
||||
|
||||
(/usr/share/texmf-dist/tex/latex/base/fontenc.sty
|
||||
Package: fontenc 2025/07/18 v2.1d Standard LaTeX package
|
||||
)
|
||||
(/usr/share/texmf-dist/tex/latex/fontspec/fontspec.cfg)))
|
||||
|
||||
Package fontspec Info:
|
||||
(fontspec) Hurmit Nerd Font Mono scale = 0.7.
|
||||
|
||||
|
||||
Package fontspec Info:
|
||||
(fontspec) Hurmit Nerd Font Mono scale = 0.7.
|
||||
|
||||
|
||||
Package fontspec Info:
|
||||
(fontspec) Hurmit Nerd Font Mono/B scale = 0.7.
|
||||
|
||||
|
||||
Package fontspec Info:
|
||||
(fontspec) Hurmit Nerd Font Mono/I scale = 0.7.
|
||||
|
||||
|
||||
Package fontspec Info:
|
||||
(fontspec) Hurmit Nerd Font Mono/BI scale = 0.7.
|
||||
|
||||
|
||||
Package fontspec Info:
|
||||
(fontspec) Font family 'HurmitNerdFontMono(0)' created for font
|
||||
(fontspec) 'Hurmit Nerd Font Mono' with options
|
||||
(fontspec) [WordSpace={1,0,0},HyphenChar=None,PunctuationSpace=Word
|
||||
Space,Scale=0.7].
|
||||
(fontspec)
|
||||
(fontspec) This font family consists of the following NFSS
|
||||
(fontspec) series/shapes:
|
||||
(fontspec)
|
||||
(fontspec) - 'normal' (m/n) with NFSS spec.: <->s*[0.7]"Hurmit
|
||||
(fontspec) Nerd Font Mono/OT:script=DFLT;language=dflt;"
|
||||
(fontspec) - 'bold' (b/n) with NFSS spec.: <->s*[0.7]"Hurmit Nerd
|
||||
(fontspec) Font Mono/B/OT:script=DFLT;language=dflt;"
|
||||
(fontspec) - 'italic' (m/it) with NFSS spec.: <->s*[0.7]"Hurmit
|
||||
(fontspec) Nerd Font Mono/I/OT:script=DFLT;language=dflt;"
|
||||
(fontspec) - 'bold italic' (b/it) with NFSS spec.:
|
||||
(fontspec) <->s*[0.7]"Hurmit Nerd Font
|
||||
(fontspec) Mono/BI/OT:script=DFLT;language=dflt;"
|
||||
|
||||
|
||||
No file main.aux.
|
||||
\openout1 = `main.aux'.
|
||||
|
||||
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 11.
|
||||
LaTeX Font Info: ... okay on input line 11.
|
||||
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 11.
|
||||
LaTeX Font Info: ... okay on input line 11.
|
||||
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 11.
|
||||
LaTeX Font Info: ... okay on input line 11.
|
||||
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 11.
|
||||
LaTeX Font Info: ... okay on input line 11.
|
||||
LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 11.
|
||||
LaTeX Font Info: ... okay on input line 11.
|
||||
LaTeX Font Info: Checking defaults for TU/lmr/m/n on input line 11.
|
||||
LaTeX Font Info: ... okay on input line 11.
|
||||
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 11.
|
||||
LaTeX Font Info: ... okay on input line 11.
|
||||
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 11.
|
||||
LaTeX Font Info: ... okay on input line 11.
|
||||
*geometry* driver: auto-detecting
|
||||
*geometry* detected driver: xetex
|
||||
*geometry* verbose mode - [ preamble ] result:
|
||||
* driver: xetex
|
||||
* paper: a4paper
|
||||
* layout: <same size as paper>
|
||||
* layoutoffset:(h,v)=(0.0pt,0.0pt)
|
||||
* modes:
|
||||
* h-part:(L,W,R)=(72.26999pt, 452.9679pt, 72.26999pt)
|
||||
* v-part:(T,H,B)=(72.26999pt, 700.50687pt, 72.26999pt)
|
||||
* \paperwidth=597.50787pt
|
||||
* \paperheight=845.04684pt
|
||||
* \textwidth=452.9679pt
|
||||
* \textheight=700.50687pt
|
||||
* \oddsidemargin=0.0pt
|
||||
* \evensidemargin=0.0pt
|
||||
* \topmargin=-37.0pt
|
||||
* \headheight=12.0pt
|
||||
* \headsep=25.0pt
|
||||
* \topskip=10.0pt
|
||||
* \footskip=30.0pt
|
||||
* \marginparwidth=57.0pt
|
||||
* \marginparsep=11.0pt
|
||||
* \columnsep=10.0pt
|
||||
* \skip\footins=9.0pt plus 4.0pt minus 2.0pt
|
||||
* \hoffset=0.0pt
|
||||
* \voffset=0.0pt
|
||||
* \mag=1000
|
||||
* \@twocolumnfalse
|
||||
* \@twosidefalse
|
||||
* \@mparswitchfalse
|
||||
* \@reversemarginfalse
|
||||
* (1in=72.27pt=25.4mm, 1cm=28.453pt)
|
||||
|
||||
|
||||
Package fontspec Info:
|
||||
(fontspec) Adjusting the maths setup (use [no-math] to avoid
|
||||
(fontspec) this).
|
||||
|
||||
\symlegacymaths=\mathgroup4
|
||||
LaTeX Font Info: Overwriting symbol font `legacymaths' in version `bold'
|
||||
(Font) OT1/cmr/m/n --> OT1/cmr/bx/n on input line 11.
|
||||
LaTeX Font Info: Redeclaring math accent \acute on input line 11.
|
||||
LaTeX Font Info: Redeclaring math accent \grave on input line 11.
|
||||
LaTeX Font Info: Redeclaring math accent \ddot on input line 11.
|
||||
LaTeX Font Info: Redeclaring math accent \tilde on input line 11.
|
||||
LaTeX Font Info: Redeclaring math accent \bar on input line 11.
|
||||
LaTeX Font Info: Redeclaring math accent \breve on input line 11.
|
||||
LaTeX Font Info: Redeclaring math accent \check on input line 11.
|
||||
LaTeX Font Info: Redeclaring math accent \hat on input line 11.
|
||||
LaTeX Font Info: Redeclaring math accent \dot on input line 11.
|
||||
LaTeX Font Info: Redeclaring math accent \mathring on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \colon on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \Gamma on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \Delta on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \Theta on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \Lambda on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \Xi on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \Pi on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \Sigma on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \Upsilon on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \Phi on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \Psi on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \Omega on input line 11.
|
||||
LaTeX Font Info: Redeclaring math symbol \mathdollar on input line 11.
|
||||
LaTeX Font Info: Redeclaring symbol font `operators' on input line 11.
|
||||
LaTeX Font Info: Encoding `OT1' has changed to `TU' for symbol font
|
||||
(Font) `operators' in the math version `normal' on input line 11.
|
||||
LaTeX Font Info: Overwriting symbol font `operators' in version `normal'
|
||||
(Font) OT1/cmr/m/n --> TU/lmr/m/n on input line 11.
|
||||
LaTeX Font Info: Encoding `OT1' has changed to `TU' for symbol font
|
||||
(Font) `operators' in the math version `bold' on input line 11.
|
||||
LaTeX Font Info: Overwriting symbol font `operators' in version `bold'
|
||||
(Font) OT1/cmr/bx/n --> TU/lmr/m/n on input line 11.
|
||||
LaTeX Font Info: Overwriting symbol font `operators' in version `normal'
|
||||
(Font) TU/lmr/m/n --> TU/lmr/m/n on input line 11.
|
||||
LaTeX Font Info: Overwriting math alphabet `\mathit' in version `normal'
|
||||
(Font) OT1/cmr/m/it --> TU/lmr/m/it on input line 11.
|
||||
LaTeX Font Info: Overwriting math alphabet `\mathbf' in version `normal'
|
||||
(Font) OT1/cmr/bx/n --> TU/lmr/b/n on input line 11.
|
||||
LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `normal'
|
||||
(Font) OT1/cmss/m/n --> TU/lmss/m/n on input line 11.
|
||||
LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `normal'
|
||||
(Font) OT1/cmtt/m/n --> TU/HurmitNerdFontMono(0)/m/n on input
|
||||
line 11.
|
||||
LaTeX Font Info: Overwriting symbol font `operators' in version `bold'
|
||||
(Font) TU/lmr/m/n --> TU/lmr/b/n on input line 11.
|
||||
LaTeX Font Info: Overwriting math alphabet `\mathit' in version `bold'
|
||||
(Font) OT1/cmr/bx/it --> TU/lmr/b/it on input line 11.
|
||||
LaTeX Font Info: Overwriting math alphabet `\mathsf' in version `bold'
|
||||
(Font) OT1/cmss/bx/n --> TU/lmss/b/n on input line 11.
|
||||
LaTeX Font Info: Overwriting math alphabet `\mathtt' in version `bold'
|
||||
(Font) OT1/cmtt/m/n --> TU/HurmitNerdFontMono(0)/b/n on input
|
||||
line 11.
|
||||
LaTeX Font Info: External font `cmex10' loaded for size
|
||||
(Font) <7> on input line 14.
|
||||
LaTeX Font Info: External font `cmex10' loaded for size
|
||||
(Font) <5> on input line 14.
|
||||
LaTeX Font Info: Font shape `TU/HurmitNerdFontMono(0)/m/n' will be
|
||||
(Font) scaled to size 6.99997pt on input line 22.
|
||||
|
||||
LaTeX Warning: Float too large for page by 44.293pt on input line 93.
|
||||
|
||||
[1
|
||||
|
||||
] [2] (./main.aux)
|
||||
***********
|
||||
LaTeX2e <2025-11-01>
|
||||
L3 programming layer <2026-01-19>
|
||||
***********
|
||||
)
|
||||
Here is how much of TeX's memory you used:
|
||||
3526 strings out of 470191
|
||||
106539 string characters out of 5479698
|
||||
562689 words of memory out of 5000000
|
||||
32135 multiletter control sequences out of 15000+600000
|
||||
627857 words of font info for 57 fonts, out of 8000000 for 9000
|
||||
14 hyphenation exceptions out of 8191
|
||||
73i,9n,93p,432b,328s stack positions out of 10000i,1000n,20000p,200000b,200000s
|
||||
|
||||
Output written on main.pdf (2 pages).
|
||||
Binary file not shown.
@@ -59,6 +59,7 @@
|
||||
\languageline{expression}{\texttt{FVNCTIO} \texttt{(} \textit{optional-ids} \texttt{)} \texttt{VT} \textit{scope}} \\
|
||||
\languageline{expression}{\textit{literal}} \\
|
||||
\languageline{expression}{\textit{expression} \texttt{[} \textit{expression} \texttt{]}} \\
|
||||
\languageline{expression}{\textit{expression} \texttt{[} \textit{expression} \texttt{VSQVE} \textit{expression} \texttt{]} \textnormal{\small\ (inclusive slice)}} \\
|
||||
\languageline{expression}{\textit{expression} \textbf{binop} \textit{expression}} \\
|
||||
\languageline{expression}{\textbf{unop} \textit{expression}} \\ \hline
|
||||
\languageline{literal}{\textbf{string}} \\
|
||||
|
||||
2
snippets/array_slice.cent
Normal file
2
snippets/array_slice.cent
Normal file
@@ -0,0 +1,2 @@
|
||||
DESIGNA x VT [X, XX, XXX, XL, L]
|
||||
DICE(x[II VSQVE IV])
|
||||
BIN
snippets/array_slice.png
Normal file
BIN
snippets/array_slice.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
68
tests.py
68
tests.py
@@ -11,7 +11,7 @@ from parameterized import parameterized
|
||||
from fractions import Fraction
|
||||
|
||||
from centvrion.ast_nodes import (
|
||||
ArrayIndex, Bool, BinOp, BuiltIn, DataArray, DataDict, DataRangeArray,
|
||||
ArrayIndex, ArraySlice, Bool, BinOp, BuiltIn, DataArray, DataDict, DataRangeArray,
|
||||
Defini, Continva, Designa, DesignaDestructure, DesignaIndex, DumStatement,
|
||||
Erumpe, ExpressionStatement, Fvnctio, ID, InterpolatedString, Invoca,
|
||||
ModuleCall, Nullus, Numeral, PerStatement, Program, Redi, SiStatement,
|
||||
@@ -673,6 +673,15 @@ error_tests = [
|
||||
("DESIGNA a, b VT III", CentvrionError), # destructure non-array
|
||||
("DESIGNA a, b VT [I]", CentvrionError), # destructure length mismatch: too many targets
|
||||
("DESIGNA a, b VT [I, II, III]", CentvrionError), # destructure length mismatch: too few targets
|
||||
("[I, II, III][II VSQVE IV]", CentvrionError), # slice upper bound out of range
|
||||
("[I, II, III][NVLLVS VSQVE II]", CentvrionError), # slice with non-integer bound
|
||||
("I[I VSQVE II]", CentvrionError), # slice on non-array
|
||||
("[I, II, III][III VSQVE I]", CentvrionError), # slice from > to
|
||||
("CVM SVBNVLLA\n[I, II, III][-I VSQVE II]", CentvrionError), # slice with negative lower bound
|
||||
("CVM SVBNVLLA\n[I, II, III][I VSQVE -I]", CentvrionError), # slice with negative upper bound
|
||||
("CVM FRACTIO\n[I, II, III][IIIS VSQVE III]", CentvrionError), # slice with fractional lower bound
|
||||
("CVM FRACTIO\n[I, II, III][I VSQVE IIIS]", CentvrionError), # slice with fractional upper bound
|
||||
("CVM FRACTIO\n[I, II, III][I / II VSQVE III]", CentvrionError), # slice with division-fraction lower bound
|
||||
]
|
||||
|
||||
class TestErrors(unittest.TestCase):
|
||||
@@ -1517,6 +1526,63 @@ class TestArrayIndexAssign(unittest.TestCase):
|
||||
run_test(self, source, nodes, value)
|
||||
|
||||
|
||||
# --- Array slicing ---
|
||||
|
||||
array_slice_tests = [
|
||||
# basic slice from middle
|
||||
("[X, XX, XXX, XL, L][II VSQVE IV]",
|
||||
Program([], [ExpressionStatement(ArraySlice(
|
||||
DataArray([Numeral("X"), Numeral("XX"), Numeral("XXX"), Numeral("XL"), Numeral("L")]),
|
||||
Numeral("II"), Numeral("IV")))]),
|
||||
ValList([ValInt(20), ValInt(30), ValInt(40)])),
|
||||
# slice of length 1
|
||||
("[I, II, III][II VSQVE II]",
|
||||
Program([], [ExpressionStatement(ArraySlice(
|
||||
DataArray([Numeral("I"), Numeral("II"), Numeral("III")]),
|
||||
Numeral("II"), Numeral("II")))]),
|
||||
ValList([ValInt(2)])),
|
||||
# full array slice
|
||||
("[I, II, III][I VSQVE III]",
|
||||
Program([], [ExpressionStatement(ArraySlice(
|
||||
DataArray([Numeral("I"), Numeral("II"), Numeral("III")]),
|
||||
Numeral("I"), Numeral("III")))]),
|
||||
ValList([ValInt(1), ValInt(2), ValInt(3)])),
|
||||
# slice on variable
|
||||
("DESIGNA a VT [I, II, III, IV, V]\na[II VSQVE IV]",
|
||||
Program([], [
|
||||
Designa(ID("a"), DataArray([Numeral("I"), Numeral("II"), Numeral("III"), Numeral("IV"), Numeral("V")])),
|
||||
ExpressionStatement(ArraySlice(ID("a"), Numeral("II"), Numeral("IV"))),
|
||||
]),
|
||||
ValList([ValInt(2), ValInt(3), ValInt(4)])),
|
||||
# slice then index (chained)
|
||||
("[I, II, III, IV][I VSQVE III][II]",
|
||||
Program([], [ExpressionStatement(ArrayIndex(
|
||||
ArraySlice(
|
||||
DataArray([Numeral("I"), Numeral("II"), Numeral("III"), Numeral("IV")]),
|
||||
Numeral("I"), Numeral("III")),
|
||||
Numeral("II")))]),
|
||||
ValInt(2)),
|
||||
# slice on range array
|
||||
("[I VSQVE X][III VSQVE VII]",
|
||||
Program([], [ExpressionStatement(ArraySlice(
|
||||
DataRangeArray(Numeral("I"), Numeral("X")),
|
||||
Numeral("III"), Numeral("VII")))]),
|
||||
ValList([ValInt(3), ValInt(4), ValInt(5), ValInt(6), ValInt(7)])),
|
||||
# expression as slice bounds
|
||||
("[I, II, III, IV, V][I + I VSQVE II + II]",
|
||||
Program([], [ExpressionStatement(ArraySlice(
|
||||
DataArray([Numeral("I"), Numeral("II"), Numeral("III"), Numeral("IV"), Numeral("V")]),
|
||||
BinOp(Numeral("I"), Numeral("I"), "SYMBOL_PLUS"),
|
||||
BinOp(Numeral("II"), Numeral("II"), "SYMBOL_PLUS")))]),
|
||||
ValList([ValInt(2), ValInt(3), ValInt(4)])),
|
||||
]
|
||||
|
||||
class TestArraySlice(unittest.TestCase):
|
||||
@parameterized.expand(array_slice_tests)
|
||||
def test_array_slice(self, source, nodes, value):
|
||||
run_test(self, source, nodes, value)
|
||||
|
||||
|
||||
# --- Comments ---
|
||||
|
||||
comment_tests = [
|
||||
|
||||
Reference in New Issue
Block a user