mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-22 23:48:30 +00:00
81 lines
2.5 KiB
C
81 lines
2.5 KiB
C
#ifndef BIND_STACK_H
|
|
#define BIND_STACK_H
|
|
|
|
#include "containers/mlrval.h"
|
|
#include "containers/lhmsmv.h"
|
|
|
|
// Bound & scoped variables for use in for-loops, function bodies, and
|
|
// subroutine bodies. A frame is 'fenced' if it's at entry to a
|
|
// function/subroutine body. Example:
|
|
//
|
|
// mlr ... put -f '
|
|
// func f(x) {
|
|
// return k;
|
|
// }
|
|
// for (k,v in $*) {
|
|
// $[k] = f(v)
|
|
// }
|
|
// '
|
|
//
|
|
// There is a bind-stack created on entering the put. A frame is pushed in the
|
|
// for-loop. A second frame is pushed in the call to f(x). The former should
|
|
// have access to k; the latter should not.
|
|
|
|
// ----------------------------------------------------------------
|
|
// Data private to .c file
|
|
typedef struct _bind_stack_frame_t bind_stack_frame_t;
|
|
|
|
typedef struct _bind_stack_t {
|
|
int num_used;
|
|
int num_allocated;
|
|
bind_stack_frame_t** ppframes;
|
|
bind_stack_frame_t* pbase_frame;
|
|
} bind_stack_t;
|
|
|
|
// ----------------------------------------------------------------
|
|
// Constructors/destructors
|
|
|
|
bind_stack_t* bind_stack_alloc();
|
|
void bind_stack_free(bind_stack_t* pstack);
|
|
|
|
bind_stack_frame_t* bind_stack_frame_alloc_unfenced();
|
|
bind_stack_frame_t* bind_stack_frame_alloc_fenced();
|
|
void bind_stack_frame_free(bind_stack_frame_t* pframe);
|
|
|
|
// xxx comment
|
|
bind_stack_frame_t* bind_stack_frame_enter(bind_stack_frame_t* pframe);
|
|
void bind_stack_frame_exit(bind_stack_frame_t* pframe);
|
|
|
|
// ----------------------------------------------------------------
|
|
// Scope entry/exit
|
|
|
|
// To be called on entry to scoped block
|
|
void bind_stack_push(bind_stack_t* pstack, bind_stack_frame_t* pframe);
|
|
|
|
// To be called on exit from scoped block.
|
|
bind_stack_frame_t* bind_stack_pop(bind_stack_t* pstack);
|
|
|
|
// ----------------------------------------------------------------
|
|
// Access within scope
|
|
|
|
// Use of local variables on expression right-hand sides
|
|
mv_t* bind_stack_resolve(bind_stack_t* pstack, char* key);
|
|
|
|
// Use of local variables on expression left-hand sides
|
|
// The pmv is not copied. You may wish to mv_copy the argument you pass in.
|
|
// The pmv will be freed.
|
|
|
|
// xxx cmt
|
|
void bind_stack_define(bind_stack_t* pstack, char* name, mv_t* pmv, char free_flags);
|
|
void bind_stack_set(bind_stack_t* pstack, char* name, mv_t* pmv, char free_flags);
|
|
|
|
// Clears the binding from the top frame without popping it. Useful
|
|
// for clearing the baseframe which is never popped.
|
|
void bind_stack_clear(bind_stack_t* pstack);
|
|
|
|
// ----------------------------------------------------------------
|
|
// Test/debug
|
|
|
|
void bind_stack_print(bind_stack_t* pstack);
|
|
|
|
#endif // BIND_STACK_H
|