structures: value & memory model fixes (embed memory into the values), functions fixes (rerite with new syntax)

This commit is contained in:
ProgramSnail 2026-04-14 11:32:28 +00:00
parent 6a3368cbdf
commit 57bb3a72ec

View file

@ -79,7 +79,7 @@
// NOTE: do not use names in type // NOTE: do not use names in type
// Or[$lambda_((x type)+)$][type of lambda or function pointer, defined by function declaration] // `Fun` // Or[$lambda_((x type)+)$][type of lambda or function pointer, defined by function declaration] // `Fun`
Or[$lambda_(type+)$][type of lambda or function pointer, defined by function declaration] // `Fun` Or[$lambda type+$][type of lambda or function pointer, defined by function declaration] // `Fun`
} }
), ),
// FIXME: replace with expr // FIXME: replace with expr
@ -122,62 +122,70 @@
== Value Model == Value Model
#let rf = $\& #h(3pt)$
// FIXME: check & add details // FIXME: check & add details
#let deepvalue = `deepvalue`
#let value = `value` #let value = `value`
#bnf( #bnf(
Prod( Prod(
`value`, $deepvalue$,
{ {
Or[$()$][value of simple type] // `Unit` Or[$0$][valid value of simple type] // `Unit`
Or[$lambda_X$][function pointer value] // `Fun` Or[$\#$][valid or spoiled value of simple type] // `Unit`
Or[$\& #h(3pt) value$][reference value] // `Ref` Or[$bot$][spoiled value of simple type] // `Unit`
Or[$lambda type+ stmt$][function pointer value] // `Fun`
Or[$rf deepvalue$][reference value, contains label of the value in the memory] // `Ref`
Or[$[deepvalue+]$][tuple value] // `Prod`
}
),
Prod(
$value_mu$,
{
Or[$0$][valid value of simple type] // `Unit`
Or[$\#$][valid or spoiled value of simple type] // `Unit`
Or[$bot$][spoiled value of simple type] // `Unit`
Or[$lambda type+ stmt$][function pointer value] // `Fun`
Or[$rf LL$][reference value, contains label of the value in the memory] // `Ref`
Or[$[value+]$][tuple value] // `Prod` Or[$[value+]$][tuple value] // `Prod`
} }
), ),
) )
$value$ - значения, которые могут лежать в переменных и передаваться как аргументы функций (то, во что вычисляется $expr$) #deepvalue - полное значение, #value - слой значения, привязан к конкретной памяти $mu$
Значения, могут лежать в переменных и передаваться как аргументы функций (то, во что вычисляется $expr$)
$v in value$ - произвольное значение
Получение #value по #deepvalue:
- $rf LL xarrowSquiggly(mu)_#[deep] rf mu[LL]$
- $* xarrowSquiggly(mu)_#[deep] *$
где $*$ - произвольный конструктор значения кроме $rf$
== Memory Model == Memory Model
// FIXME: check & add details #let cl = $chevron.l$
#let memelem = `memelem` #let cr = $chevron.r$
#let valuemem = `valuemem`
#bnf(
Prod(
`memelem`,
{
Or[$0$][cell with some value (always)]
Or[$\#$][cell with possible value or $bot$]
Or[$bot$][spoiled cell (always)]
}
),
Prod(
`valuemem`,
{
Or[$()$][one unit of memory, for simple vars] // `Unit`
Or[$lambda$][memory for lambda or function pointer, is not important in the memory model, 0 units] // `Fun`
Or[$\& #h(3pt) LL valuemem$][reference to structure memory start] // `Ref`
Or[$[valuemem+]$][memory specification for each tuple member] // `Prod`
}
),
)
#let mem = `mem` #let mem = `mem`
Память преставляется в виде стека из значений `memelem`:
- $LL = NN$ - множество меток памяти
- $mu : mem = LL -> V$ - память, частично определённая функция
- $l in LL$ - длина используемого фрагмента памяти
Каждому значению $value$ в соответствие ставится $valuemem$ - расположние этого значения в пaмяти - $LL$ - множество меток памяти
- $mem := LL -> value, space mu : mem$ - память, частично определённая функция
- $l in LL$ - новый тег памяти (ранее не использованный)
- `next` - получение следующей неиспользованной метки
Соответствие: #align(center, prooftree(
- $() -> ()$ vertical-spacing: 4pt,
- $lambda_X -> lambda$ rule(
- $\& #h(3pt) value -> \& #h(3pt) LL valuemem$ name: [ add value to memory],
- $[value+] -> [valuemem+]$
// TODO: move allocation semantics there ?? $l' = #[next] (l)$,
// TODO: check that access is what required ??
$cl mu, l cr xarrowSquiggly(v)_#[add] cl mu [l <- v], l' cr$,
)
))
== Semantics == Semantics
@ -185,14 +193,24 @@ $value$ - значения, которые могут лежать в перем
$X$ - можество переменных $X$ - можество переменных
// FIXME: TMP
#let valuemem = `valuemem`
#let memelem = `memelem`
#let pathenvmode = `pathenvmode`
#let pathenvval = `pathenvval`
#let pathenvmem = `pathenvmem`
#let pathenvtype = `pathenvtype`
#let env = `env` #let env = `env`
$sigma : env = X -> valuemem times type$ - #[ позиции памяти, соответстующие переменным контекста, частично определённая функция ] $sigma : env := X -> LL times type, space sigma : env$ - #[ метки памяти и типы значений пеерменных контекста, частично определённая функция ]
$DD : X -> decl$ - глобальные определения, частично определённая функция // $DD : X -> decl$ - глобальные определения, частично определённая функция
$d in decl, s in stmt, f in X, x in X, a in X$ // $d in decl, $
$s in stmt, f in X, x in X, a in X$
$d space @ space overline(x)$ - запись применения функции (вида #decl) к аргументам // FIXME ??
// $d space @ space overline(x)$ - запись применения функции (вида #decl) к аргументам
=== Path Accessors === Path Accessors
@ -200,93 +218,215 @@ $d space @ space overline(x)$ - запись применения функции
Для удобства значение, получаемое из текущего применением пути, будем называть полем. Для удобства значение, получаемое из текущего применением пути, будем называть полем.
// Все эти функции используются с префиксом `path.`. // Все эти функции используются с префиксом `path.`.
// FIXME: types & description for functios #let eqmu = $attach(=, br: mu)$
#let pathtype = `path.type` #let arrmu = $attach(->, br: mu)$
#let pathmem = `path.mem`
#let pathmode = `path.mode`
#let pathvar = `path.var`
#let pathsize = `path.memsize` #let ttype = $attach(tack.r, br: type)$
#let pathbasepos = `path.membasepos` #let tpath = $attach(tack.r, br: path)$
#let pathoffset = `path.memoffset` #let tmode = $attach(tack.r, br: mode)$
#let pathpos = `path.mempos`
#let pathenvtype = `path.envtype` #let val = `val`
#let pathenvmem = `path.envmem` #let label = `label`
#let pathenvmode = `path.envmode` #let tval = $attach(tack.r, br: val)$
#let tlabel = $attach(tack.r, br: label)$
#let pathenvpos = `path.envpos` #let tetype = $attach(tack.r.double, br: type)$
#let pathenvval = `path.envval` #let temode = $attach(tack.r.double, br: mode)$
#let teval = $attach(tack.r.double, br: val)$
#let telabel = $attach(tack.r.double, br: label)$
// TODO: env mem label ??, env mem value ??
// TODO: FIXME: backwards, deconstruction ??
- #[ Конструирование путей по переменой
#align(center, prooftree(
vertical-spacing: 4pt,
rule(
name: [ variable path],
$x tpath @x$,
)
))
#align(center, prooftree(
vertical-spacing: 4pt,
rule(
name: [ reference path],
$x tpath p$,
$x tpath rf p$,
)
))
#align(center, prooftree(
vertical-spacing: 4pt,
rule(
name: [ access path],
$x tpath p$,
$x tpath p.i$,
)
))
]
- #[ Получение типа поля - #[ Получение типа поля
$ pathtype : type -> path -> type $ #align(center, prooftree(
$ pathtype(t, @x) = t $ vertical-spacing: 4pt,
$ pathtype(\& #h(3pt) mode #h(3pt) t, *p) = pathtype(t, p) $ rule(
$ pathtype([t_1, t_2, ..., t_n], p.i) = pathtype(t_i, p) $ name: [ variable typing],
$x : t_x ttype @x : t_x$,
)
))
#align(center, prooftree(
vertical-spacing: 4pt,
rule(
name: [ reference typing],
$x tpath p$,
$x : t_x ttype p : rf mode t_p$,
$x : t_x ttype *p : t_p$,
)
))
#align(center, prooftree(
vertical-spacing: 4pt,
rule(
name: [ access typing],
$x tpath p$,
$x : t_x ttype p : [t_1, ... t_n]$,
$x : t_x ttype p.i : t_i$,
)
))
] ]
- #[ Получение начала памяти поля (предусловие: $pathtype(t, p) = \& #h(3pt) ...$)
$ pathmem : valuemem -> path -> LL $ - #[ Получение тега поля
$ pathmem(\& #h(3pt) y m, @x) = y $ // NOTE: only memory for refsi in midel ?? // TODO: decide #align(center, prooftree(
$ pathmem(\& #h(3pt) y m, *p) = pathmem(m, p) $ vertical-spacing: 4pt,
$ pathmem([m_1, m_2, ..., m_n], p.i) = pathmem(m_i, p) $ rule(
name: [ variable typing],
$t_x = rf mode t$,
$x : t_x tmode @x -> mode$,
)
))
#align(center, prooftree(
vertical-spacing: 4pt,
rule(
name: [ reference typing],
$x tpath p$,
$x : t_x tmode p : rf mode t_p$,
$x : t_x tmode *p : t_p$,
)
))
#align(center, prooftree(
vertical-spacing: 4pt,
rule(
name: [ access typing],
$x tpath p$,
$x : t_x tmode p : [t_1, ... t_n]$,
$x : t_x tmode p.i : t_i$,
)
))
] ]
- #[ Получения тега поля (предусловие: $pathtype(t, p) = \& #h(3pt) ...$)
$ pathmode : type -> path -> mode $ - #[ Получение значения поля
$ pathmode(\& #h(3pt) mode #h(3pt) t, @x) = mode $ #align(center, prooftree(
$ pathmode(\& #h(3pt) mode #h(3pt) t, *p) = pathmode(t, p) $ vertical-spacing: 4pt,
$ pathmode([t_1, t_2, ..., t_n], p.i) = pathmode(t_i, p) $ rule(
name: [ variable typing],
$x eqmu v_x tval @x eqmu v_x$,
)
))
#align(center, prooftree(
vertical-spacing: 4pt,
rule(
name: [ reference typing],
$x tpath p$,
$x eqmu v_x tval p eqmu rf l$,
$x eqmu v_x tval *p eqmu mu[l]$,
)
))
#align(center, prooftree(
vertical-spacing: 4pt,
rule(
name: [ access typing],
$x tpath p$,
$x eqmu v_x tmode p eqmu [v_1, ... v_n]$,
$x eqmu v_x tmode p.i eqmu v_i$,
)
))
] ]
- #[ Получение \"корневой\" переменной пути
$ pathvar : path -> X $ - #[ Получение метки поля
$ pathvar(@x) = x $ #align(center, prooftree(
$ pathvar(* p) = pathvar(p) $ vertical-spacing: 4pt,
$ pathvar(p.i) = pathvar(p) $ rule(
] name: [ variable typing],
- #[ Получение размера поля в памяти
$ pathsize : valuemem -> path -> LL $ $v_x = rf l$,
$ pathsize((), @x) = 1 $
$ pathsize(lambda, @x) = 0 $ $x eqmu v_x tval p eqmu rf l$,
$ pathsize(\& #h(3pt) y m, @x) = 0 $ // TODO: FIXME ?? always disconnected location ?? $x eqmu v_x tmode p arrmu l$,
$ pathsize([m_1, m_2, ..., m_n], @x) = pathsize(m_1, @x) + ... + pathsize(m_n, @x) $ )
$ pathsize(\& #h(3pt) y m, *p) = pathsize(m, p) $ ))
$ pathsize([m_1, m_2, ..., m_n], p.i) = pathsize(m_i, p) $
]
// TODO: FIXME ??
- #[ Получение позиции последного ссылочного предка поля в пaмяти
$ pathbasepos : value -> path -> X $
// $ pathbasepos(m, @x) = bot $ // NOTE: trivial if not present ??
$ pathbasepos(\& #h(3pt) y m, *p) = pathbasepos(m, p) | y $
$ pathbasepos([m_1, m_2, ..., m_n], p.i) = pathbasepos(m_i, p) $
]
- #[ Получение смещения поля в последнем монолитном отрезке памяти
$ pathoffset : value -> path -> X $
$ pathoffset(m, @x) = 0 $
$ pathoffset(\& #h(3pt) y m, *p) = pathoffset(m, p) $
$ pathoffset([m_1, m_2, ..., m_n], p.i) = (i - 1) + pathoffset(m_i, p) $
]
- #[ Получение позиции поля в пaмяти
$ pathpos : value -> path -> X $
$ pathpos(m, p) = pathbasepos(m, p) + pathoffset(m, p)$
] ]
- #[ Получение типа поля по окружению - #[ Получение типа поля по окружению
$ pathenvtype : env -> path -> type $ #align(center, prooftree(
$ pathenvtype(sigma, p) = pathtype(sigma[pathvar(p)].2, p) $ vertical-spacing: 4pt,
rule(
name: [ access typing],
$x tpath p$,
$x : sigma[x].2 ttype p : t$,
$sigma tetype p : t$,
)
))
] ]
- #[ Получение начала памяти поля по окружению (предусловие: $pathtype(t, p) = \& #h(3pt) ...$)
$ pathenvmem : env -> path -> LL $ - #[ Получение тега поля по окружению
$ pathenvmem(sigma, p) = pathmem(sigma[pathvar(p)].1, p) $ #align(center, prooftree(
vertical-spacing: 4pt,
rule(
name: [ access typing],
$x tpath p$,
$x : sigma[x].2 tmode p -> mode$,
$sigma temode p -> mode$,
)
))
] ]
- #[ Получения тега поля по окружению (предусловие: $pathtype(t, p) = \& #h(3pt) ...$)
$ pathenvmode : env -> path -> mode $ - #[ Получение значения поля по окружению
$ pathenvmode(sigma, p) = pathmode(sigma[pathvar(p)].2, p) $ #align(center, prooftree(
vertical-spacing: 4pt,
rule(
name: [ access typing],
$x tpath p$,
$x eqmu sigma[x].1 tval p eqmu v$,
$sigma, mu teval p eqmu x$,
)
))
] ]
- #[ Получение позиции поля в пaмяти по окружению
$ pathenvpos : env -> path -> X $ - #[ Получение метки поля по окружению
$ pathenvpos(m, p) = pathpos(sigma[pathvar(p)].1, p)$ #align(center, prooftree(
] vertical-spacing: 4pt,
- #[ Получение поля в пaмяти rule(
$ pathenvval : env -> mem -> path -> memelem $ name: [ access typing],
$ pathenvval(sigma, mu, p) = mu[pathenvpos(sigma, p)]$
$x tpath p$,
$x eqmu sigma[x].1 tlabel p arrmu l$,
$sigma, mu telabel p arrmu l$,
)
))
] ]
=== Mode Correctness === Mode Correctness
@ -325,9 +465,6 @@ $ isRead mode -> isIn mode $
#let copy = `copy` #let copy = `copy`
#let read = `read` #let read = `read`
#let cl = $chevron.l$
#let cr = $chevron.r$
// #align(center, grid( // #align(center, grid(
// columns: 3, // columns: 3,
// gutter: 5%, // gutter: 5%,