Skip to content

Commit

Permalink
even more safe table operations
Browse files Browse the repository at this point in the history
  • Loading branch information
borisbat committed Dec 11, 2024
1 parent 7c69126 commit 38b3ff3
Show file tree
Hide file tree
Showing 18 changed files with 151 additions and 87 deletions.
2 changes: 1 addition & 1 deletion daslib/archive.das
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def public serialize ( var arch:Archive; var value : table<auto(KT);auto(VT)> )
for _ in range(len)
var k : KT-const-&-#
arch |> _::serialize(k)
arch |> _::serialize(value[k])
arch |> _::serialize(unsafe(value[k]))
else
var len = length(value)
arch |> write_raw(len)
Expand Down
8 changes: 4 additions & 4 deletions daslib/debug.das
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def private resolve_path_cache(path: string; paths: array<string>; aliases: tabl
if cache |> key_exists(path)
return cache?[path] ?? ""
let absPath = resolve_path(path, paths, aliases)
cache[path] = absPath
cache |> insert(path,absPath)
return absPath

def private bytes_hr(value : uint64)
Expand Down Expand Up @@ -760,7 +760,7 @@ class private DAgent: DapiDebugAgent

pathAliases |> clear()
for k, v in keys(aliases), values(aliases)
pathAliases[k] = v
pathAliases |> insert(k,v)

def override onUninstall(agent:DebugAgent?)
if agent == thisAgent
Expand Down Expand Up @@ -1336,7 +1336,7 @@ class private DAServer: Server
let aliasesList & = unsafe(aliases as _object)
for k, v in keys(aliasesList), values(aliasesList)
if v is _string
pathAliases[k] = v as _string
pathAliases |> insert(k, v as _string)
agent->setPaths(resPaths, pathAliases)

def setDebuggerSettings(data: JsonValue?)
Expand Down Expand Up @@ -1674,7 +1674,7 @@ class private DAServer: Server
ctxData.stack[frame] |> iter_top_child_var() <| $(child)
if child.typeInfo != null
let tInfo & = unsafe(*child.typeInfo)
vars[child.name] <- [[Result tinfo=tInfo, value=child.rawValue, data=unsafe(reinterpret<void?>child.address)]]
vars |> emplace(child.name, [[Result tinfo=tInfo, value=child.rawValue, data=unsafe(reinterpret<void?>child.address)]])
--frame

var result = debug_eval(vars, ini.expression)
Expand Down
2 changes: 1 addition & 1 deletion daslib/debug_eval.das
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def expr_value ( var st : TokenStream ) : Result
elif name=="false"
return <- Result(false)
if st.names |> key_exists(name)
return st.names[name]
return st.names |> get_value(name)
return st |> error("unknown variable {name}")
if [[Token punkt='(']] // '(' expr ')
var res = expr(st)
Expand Down
4 changes: 2 additions & 2 deletions daslib/decs.das
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ def private update_entity_imm ( eid:EntityId; blk : lambda<(eid:EntityId; var cm
if lookup.generation != eid.generation
return
var cmp : ComponentMap
let arch_index = decsState.archetypeLookup[lookup.archetype]-1
let arch_index = unsafe(decsState.archetypeLookup[lookup.archetype])-1
let eidx = decsState.entityLookup[eid.id].index
var old_ahash = 0ul
if true // note - this scope is for arch &
Expand Down Expand Up @@ -612,7 +612,7 @@ def private delete_entity_imm ( eid:EntityId )
let di = decsState.entityLookup[eid.id].index
decsState.entityLookup[eid.id].generation = 0
decsState.entityFreeList |> push(eid)
remove_entity(decsState.allArchetypes[decsState.archetypeLookup[lookup.archetype]-1], di)
remove_entity(decsState.allArchetypes[unsafe(decsState.archetypeLookup[lookup.archetype])-1], di)

def public update_entity ( entityid:EntityId implicit; var blk : lambda<(eid:EntityId; var cmp:ComponentMap):void> )
//! Creates deferred action to update entity specified by id.
Expand Down
10 changes: 5 additions & 5 deletions daslib/json_boost.das
Original file line number Diff line number Diff line change
Expand Up @@ -427,14 +427,14 @@ def JV(value): JsonValue?
pass // skip void?
static_elif typeinfo(is_pointer field)
if field != null
map[name] = _::JV(field)
map |> insert(name, _::JV(field))
else
map[name] = _::JV(field)
map |> insert(name, _::JV(field))
return _::JV(map)
static_elif typeinfo(is_table value)
var map: table<string; JsonValue?>
for k, v in keys(value), values(value)
map[k] = _::JV(v)
map |> insert(k, _::JV(v))
return _::JV(map)
static_elif typeinfo(is_iterable value)
var arr: array<JsonValue?>
Expand All @@ -443,9 +443,9 @@ def JV(value): JsonValue?
return _::JV(arr)
static_elif typeinfo(is_variant value)
var map: table<string; JsonValue?>
map["$variant"] = _::JV(variant_index(value))
map |> insert("$variant", _::JV(variant_index(value)))
apply(value) <| $(name: string; field)
map[name] = _::JV(field)
map |> insert(name, _::JV(field))
return _::JV(map)
else
to_log(LOG_ERROR, "JSON: unsupported type {typeinfo(typename value)}\n")
Expand Down
8 changes: 4 additions & 4 deletions daslib/live.das
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ def private live_lookup(fn)
if appPtr==null
return false
if !liveFunctionLookup |> key_exists(fn)
liveFunctionLookup[fn] = *appPtr |> has_function(fn)
return liveFunctionLookup[fn]
liveFunctionLookup |> insert(fn, *appPtr |> has_function(fn))
return liveFunctionLookup |> get_value(fn)

def public invoke_live ( fn:string )
if live_lookup(fn)
Expand Down Expand Up @@ -142,9 +142,9 @@ def public watch_files
if stat(fileName,st)
if st.is_reg
if appTime |> key_exists(fname)
if appTime[fname] != st.mtime
if appTime |> get_value(fname) != st.mtime
any = true
appTime[fname] = st.mtime
appTime |> insert(fname, st.mtime)
return any

[export]
Expand Down
4 changes: 2 additions & 2 deletions daslib/match.das
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ def match_or ( what:TypeDeclPtr; wth:ExprOp2?; access:ExpressionPtr; var to:Matc
to.errors |> match_error("mismatching variable declarations in ||", wth.at)
return false
for k,vL in keys(toL.declarations),values(toL.declarations)
if describe(vL) != describe(toR.declarations[k])
if describe(vL) != describe(unsafe(toR.declarations[k]))
to.errors |> match_error("mismatching variable {k} declaration in ||", wth.at)
return false
delete to.declarations
Expand All @@ -384,7 +384,7 @@ def match_tag ( what:TypeDeclPtr; wth:Expression?; access:ExpressionPtr; var to:
if to.declarations |> key_exists(tname)
to.errors |> match_error("duplicate variable {tname}", tag.at)
return false
move_new(to.declarations[tname]) <| clone_expression(access)
move_new(unsafe(to.declarations[tname])) <| clone_expression(access)
log_m("\tadd variable {tname} as {describe(access)}\n")
return true
else
Expand Down
2 changes: 1 addition & 1 deletion dastest/dastest.das
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def private collect_files(input_paths: array<string>; var files: array<string>):
for path in input_paths
if path |> ends_with(".das")
if !cache |> key_exists(path)
cache[path] = null
cache |> insert(path, null)
files |> push <| path
else
if !fs::scan_dir(path, cache, files, ".das")
Expand Down
2 changes: 1 addition & 1 deletion dastest/fs.das
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@ def scan_dir(path: string; var cache: table<string; void?>; var res: array<strin
if fStat.is_dir
f |> scan_dir(cache, res)
elif fStat.is_reg && f |> ends_with(suffix) && !cache |> key_exists(f)
cache[f] = null
cache |> insert(f, null)
res |> push(f)
return true
6 changes: 3 additions & 3 deletions dastest/suite.das
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,15 @@ def test_file(file_name: string; ctx: SuiteCtx; file_ctx: FileCtx): SuiteResult
var expectedErrors : table<CompilationError; int>
if program != null
program |> for_each_expected_error <| $ ( err, count )
expectedErrors[err] = count
expectedErrors |> insert(err, count)
var failed = !ok
if ok
if !empty(output)
log::info("{output}")
elif program != null
failed = false
for err in program.errors
let count = --expectedErrors[err.cerr]
let count = --unsafe(expectedErrors[err.cerr])
if count < 0
failed = true

Expand All @@ -121,7 +121,7 @@ def test_file(file_name: string; ctx: SuiteCtx; file_ctx: FileCtx): SuiteResult
log::blue("Failed to compile {file_name}\n{output}")
if program != null
for err in program.errors
if expectedErrors[err.cerr] < 0
if expectedErrors |> get_value(err.cerr) < 0
log::error("{describe(err.at)}: {int(err.cerr)}: {err.what}")
if !empty(err.extra)
log::info("{err.extra}")
Expand Down
2 changes: 1 addition & 1 deletion modules/dasPEG/peg/parse_macro.das
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ class ParseMacro : AstCallMacro
peek_data($i(name)) <| $ ( inp )
parser.input := inp

var result : $t(gen.return_types[gram[0].name])
var result : $t(unsafe(gen.return_types[gram[0].name]))
result <- $c(parse_main_func)(parser)

if result.success
Expand Down
53 changes: 28 additions & 25 deletions modules/dasPEG/peg/parser_generator.das
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ require daslib/templates_boost
require peg/meta_ast
require detail/helpers

def get_value_and_clone_type ( var tab : table<auto(kT); TypeDeclPtr>; key : kT ) : TypeDeclPtr
unsafe
return <- tab[key] |> clone_type

struct ParserGenerator
// Provides information to generate unique names
rule_counter: table<string; int>
Expand Down Expand Up @@ -111,13 +115,12 @@ def rule_left_recursive(name: string; rule: Rule): bool

return false


def generate_wrapper(var gen: ParserGenerator)
let rule_name = gen.current_context
let cache_table = "{rule_name}_cache"
let inner_parsing_fun = "parse_{rule_name}_inner`id_{gen.id}"

var inscope return_type <- gen.return_types[rule_name] |> clone_type
var inscope return_type <- gen.return_types |> get_value_and_clone_type(rule_name)

var inscope wrapper_fun <- qmacro_function("parse_{rule_name}`id_{gen.id}") <| $ (var parser: $t(gen.parser_type)): $t(return_type)
var mark = parser.index
Expand All @@ -139,7 +142,7 @@ def generate_wrapper(var gen: ParserGenerator)
return <- result

var result <- $c(inner_parsing_fun)(parser)
parser.$f(cache_table)[mark] := result
unsafe(parser.$f(cache_table)[mark]) := result

if $v(gen.tracing)
parser.tabs--
Expand All @@ -158,7 +161,7 @@ def generate_wrapper_leftrec(var gen: ParserGenerator)
let cache_table = "{rule_name}_cache"
let inner_parsing_fun = "parse_{rule_name}_inner`id_{gen.id}"

var inscope return_type <- gen.return_types[rule_name] |> clone_type
var inscope return_type <- gen.return_types |> get_value_and_clone_type(rule_name)

var inscope wrapper_fun <- qmacro_function("parse_{rule_name}`id_{gen.id}") <| $ (var parser: $t(gen.parser_type)): $t(return_type)
var mark = parser.index
Expand Down Expand Up @@ -232,7 +235,8 @@ def generate_parser_class(var gen: ParserGenerator; parser_name: string)
if true
// Make cache table type: table<int; <result-type-for-rule>>
var inscope t2 <- qmacro_type(type<table<int; int>>)
t2.secondType |> move_new <| clone_type(gen.return_types[rule_name])
var inscope type_value <- gen.return_types |> clone_value(rule_name)
t2.secondType |> move_new <| clone_type(type_value)

s |> add_structure_field("{rule_name}_cache", t2)

Expand Down Expand Up @@ -289,22 +293,22 @@ def generate_result_types(var gen: ParserGenerator)
rule_res_type.argTypes[1] |> move_new <| clone_type(type_)

// Map name of the rule to its 'result' type
gen.return_types[rule] |> move <| rule_res_type
gen.return_types |> emplace(rule, rule_res_type)

// Also add for types for the contexts of * and ?
// They can be anything, they are used for the short-circuiting out of the current context

gen.return_types["__repetition__"] |> move_new <| make_default_type_decl()
gen.return_types["__option__"] |> move_new <| make_default_type_decl()
gen.return_types["__PEEK__"] |> move_new <| make_default_type_decl()
gen.return_types |> emplace_new("__repetition__", make_default_type_decl())
gen.return_types |> emplace_new("__option__", make_default_type_decl())
gen.return_types |> emplace_new("__PEEK__", make_default_type_decl())



def generate(var gen: ParserGenerator; var def_: Definition)
gen.current_context = def_.name

var inscope function_body <- gen |> generate(def_.rule)
var inscope return_type <- gen.return_types[gen.current_context] |> clone_type
var inscope return_type <- gen.return_types |> get_value_and_clone_type(gen.current_context)

var inscope fun <- qmacro_function("parse_{def_.name}_inner`id_{gen.id}") <| $ (var parser: $t(gen.parser_type)): $t(return_type)
$b(function_body)
Expand Down Expand Up @@ -337,10 +341,10 @@ def generate_grammar(var gen: ParserGenerator; var gram: array<Definition>; name
def get_rule_type(var gen: ParserGenerator; rule: Rule): TypeDeclPtr
match rule
if [[Rule nonterminal = $v(nonterm)]]
return <- gen.rule_types[nonterm] |> clone_type
return <- gen.rule_types |> get_value_and_clone_type(nonterm)

if [[Rule bound_nonterminal = $v(nonterm)]]
return <- gen.rule_types[nonterm._0] |> clone_type
return <- gen.rule_types |> get_value_and_clone_type(nonterm._0)

if [[Rule subrule = $v(subrule)]]
abort("Infer subrule type")
Expand All @@ -350,8 +354,7 @@ def get_rule_type(var gen: ParserGenerator; rule: Rule): TypeDeclPtr


def set_rule_type(var gen: ParserGenerator; rule_name: string; type_: TypeDeclPtr)
gen.rule_types[rule_name] |> move_new(type_ |> clone_type)

gen.rule_types |> emplace_new(rule_name, type_ |> clone_type)

def set_rule_handle(var subrule_: Rule_?; handle: string)
//! Motivating example: *CommaSeparatedElements as els
Expand Down Expand Up @@ -430,7 +433,7 @@ def generate(var gen: ParserGenerator; var rule_: Rule): array<ExpressionPtr>
let count = "{gen.rule_counter[name]++}"

// Type of the function that we are now generating code for
var inscope return_type <- gen.return_types[gen.current_context] |> clone_type
var inscope return_type <- gen.return_types |> get_value_and_clone_type(gen.current_context)

// varname is a generic name for unnamed nonterminals
// e.g. add4, add5, mul0
Expand All @@ -449,7 +452,7 @@ def generate(var gen: ParserGenerator; var rule_: Rule): array<ExpressionPtr>
let name = nonterm._0
let result_name = nonterm._1

var inscope return_type <- gen.return_types[gen.current_context] |> clone_type
var inscope return_type <- gen.return_types |> get_value_and_clone_type(gen.current_context)

let count = "{gen.rule_counter[name]++}"
let varname = "{name}{count}"
Expand All @@ -468,7 +471,7 @@ def generate(var gen: ParserGenerator; var rule_: Rule): array<ExpressionPtr>
var result_handle = subrule.name
var i = gen.rule_counter["extract"]++
var inscope subrule_ <- gen |> generate(subrule.rule)
var inscope return_type <- gen.return_types[gen.current_context] |> clone_type
var inscope return_type <- gen.return_types |> get_value_and_clone_type(gen.current_context)

var inscope t <- qmacro_block <|
var $i("ext_pos_{i}") = parser.index
Expand Down Expand Up @@ -569,7 +572,7 @@ def generate_maybe_repeat(var gen: ParserGenerator; var rule_: Rule_?): array<Ex


def generate_not(var gen: ParserGenerator; var rule_: Rule_?): array<ExpressionPtr>
var inscope return_type <- gen.return_types[gen.current_context] |> clone_type
var inscope return_type <- gen.return_types |> get_value_and_clone_type(gen.current_context)

var inscope rule_code <- gen |> with_context("__PEEK__") <|
return <- gen |> generate(rule_.rule)
Expand Down Expand Up @@ -608,7 +611,7 @@ def generate_not(var gen: ParserGenerator; var rule_: Rule_?): array<ExpressionP


def generate_and(var gen: ParserGenerator; var rule_: Rule_?): array<ExpressionPtr>
var inscope return_type <- gen.return_types[gen.current_context] |> clone_type
var inscope return_type <- gen.return_types |> get_value_and_clone_type(gen.current_context)

var inscope rule_code <- gen |> with_context("__PEEK__") <|
return <- gen |> generate(rule_.rule)
Expand Down Expand Up @@ -642,7 +645,7 @@ def generate_and(var gen: ParserGenerator; var rule_: Rule_?): array<ExpressionP

def generate_repeat(var gen: ParserGenerator; var rule_: Rule_?): array<ExpressionPtr>
var result_handle = rule_.name
var inscope return_type <- gen.return_types[gen.current_context] |> clone_type
var inscope return_type <- gen.return_types |> get_value_and_clone_type(gen.current_context)
var first_result_name = "__repeat_result_{gen.rule_counter["repeat"]++}"

if rule_.name == "" // Rule not bound by name, discard result
Expand Down Expand Up @@ -835,7 +838,7 @@ def generate_option(var gen: ParserGenerator; var rule_: Rule_?): array<Expressi

set_rule_handle(rule_, "temp_name")
var inscope type_decl <- gen |> get_rule_type(rule_.rule)
var inscope result_type <- gen.return_types[gen.current_context] |> clone_type
var inscope result_type <- gen.return_types |> get_value_and_clone_type(gen.current_context)

var inscope rule_code <- gen |> with_context("__option__") <|
return <- gen |> generate(rule_.rule)
Expand Down Expand Up @@ -875,7 +878,7 @@ def generate_one_alternative(var gen: ParserGenerator; var alt: Alternative; i;
let result = "res_{i}"

var inscope action <- alt.action
var inscope return_type <- gen.return_types[gen.current_context] |> clone_type
var inscope return_type <- gen.return_types |> get_value_and_clone_type(gen.current_context)
var inscope action_block <- action as ExprBlock |> flatten_block
var inscope block_contents <- gen |> generate(alt.rule.rule)

Expand Down Expand Up @@ -921,8 +924,8 @@ def generate_one_alternative(var gen: ParserGenerator; var alt: Alternative; i;


def alternative_add_epilogue(var block_contents: array<ExpressionPtr>; var gen: ParserGenerator; var action_block)
var inscope action_type <- gen.rule_types[gen.current_context] |> clone_type()
var inscope return_type <- gen.return_types[gen.current_context] |> clone_type()
var inscope action_type <- gen.rule_types |> get_value_and_clone_type(gen.current_context)
var inscope return_type <- gen.return_types |> get_value_and_clone_type(gen.current_context)

var inscope t <- qmacro_block <|

Expand All @@ -944,7 +947,7 @@ def alternative_add_epilogue(var block_contents: array<ExpressionPtr>; var gen:

def generate_terminal(var gen: ParserGenerator; var terminal: Terminal): ExpressionPtr
var name = "_terminal_result_{gen.rule_counter["terminal"]++}"
var inscope return_type <- gen.return_types[gen.current_context] |> clone_type()
var inscope return_type <- gen.return_types |> get_value_and_clone_type(gen.current_context)

match terminal
if [[Terminal lit = $v(l) ]]
Expand Down
Loading

0 comments on commit 38b3ff3

Please sign in to comment.