Updated symbol_table

This commit is contained in:
thomashii 2021-05-18 20:32:54 +08:00
parent 38e38c4a84
commit 082b7876b4
8 changed files with 66 additions and 27 deletions

View file

@ -1,3 +1,6 @@
# 2.0.1
* Resolved static analysis warnings
# 2.0.0
* Migrated to work with Dart SDK 2.12.x NNBD

View file

@ -1,5 +1,5 @@
# angel3_symbol_table
[![version](https://img.shields.io/badge/pub-v2.0.0-brightgreen)](https://pub.dartlang.org/packages/angel3_symbol_table)
[![version](https://img.shields.io/badge/pub-v2.0.1-brightgreen)](https://pub.dartlang.org/packages/angel3_symbol_table)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion)
@ -52,7 +52,7 @@ doubles.create('one', value: 1.0);
doubles.create('one', value: 1.0, constant: true);
// Set a variable within an ancestor, OR create a new variable if none exists.
doubles.assign('two', value: 2.0);
doubles.assign('two', 2.0);
// Completely remove a variable.
doubles.remove('two');

View file

@ -0,0 +1,4 @@
include: package:pedantic/analysis_options.yaml
analyzer:
strong-mode:
implicit-casts: false

View file

@ -0,0 +1,26 @@
import 'package:angel3_symbol_table/angel3_symbol_table.dart';
void main(List<String> args) {
var mySymbolTable = SymbolTable<int>();
var doubles =
SymbolTable<double>(values: {'hydrogen': 1.0, 'avogadro': 6.022e23});
// Create a new variable within the scope.
doubles.create('one');
doubles.create('one', value: 1.0);
doubles.create('one', value: 1.0, constant: true);
// Set a variable within an ancestor, OR create a new variable if none exists.
doubles.assign('two', 2.0);
// Completely remove a variable.
doubles.remove('two');
// Find a symbol, either in this symbol table or an ancestor.
var symbol1 = doubles.resolve('one');
// Find OR create a symbol.
var symbol2 = doubles.resolveOrCreate('one');
var symbol3 = doubles.resolveOrCreate('one', value: 1.0);
var symbol4 = doubles.resolveOrCreate('one', value: 1.0, constant: true);
}

View file

@ -17,7 +17,7 @@ class SymbolTable<T> {
/// Initializes an empty symbol table.
///
/// You can optionally provide a [Map] of starter [values].
SymbolTable({Map<String, T> values: const {}}) {
SymbolTable({Map<String, T> values = const {}}) {
if (values.isNotEmpty == true) {
values.forEach((k, v) {
_variables.add(Variable<T>._(k, this, value: v));
@ -40,7 +40,7 @@ class SymbolTable<T> {
}
/// Sets a local context for values within this scope to be resolved against.
void set context(T? value) {
set context(T? value) {
_context = value;
}
@ -59,9 +59,11 @@ class SymbolTable<T> {
SymbolTable<T>? get root {
if (_root != null) return _root;
SymbolTable<T> out = this;
var out = this;
while (out._parent != null) out = out._parent!;
while (out._parent != null) {
out = out._parent!;
}
return _root = out;
}
@ -73,8 +75,8 @@ class SymbolTable<T> {
///
/// This list is unmodifiable.
List<Variable<T>> get allVariables {
List<String> distinct = [];
List<Variable<T>> out = [];
var distinct = <String>[];
var out = <Variable<T>>[];
void crawl(SymbolTable<T> table) {
for (var v in table._variables) {
@ -111,8 +113,8 @@ class SymbolTable<T> {
///
/// This list is unmodifiable.
List<Variable<T>> allVariablesWithVisibility(Visibility visibility) {
List<String> distinct = [];
List<Variable<T>> out = [];
var distinct = <String>[];
var out = <Variable<T>>[];
void crawl(SymbolTable<T> table) {
for (var v in table._variables) {
@ -151,12 +153,13 @@ class SymbolTable<T> {
/// You may optionally provide a [value], or mark the variable as [constant].
Variable<T> create(String name, {T? value, bool? constant}) {
// Check if it exists first.
if (_variables.any((v) => v.name == name))
if (_variables.any((v) => v.name == name)) {
throw StateError(
'A symbol named "$name" already exists within the current context.');
}
_wipeLookupCache(name);
Variable<T> v = Variable._(name, this, value: value);
var v = Variable<T>._(name, this, value: value);
if (constant == true) v.lock();
_variables.add(v);
return v;
@ -208,12 +211,13 @@ class SymbolTable<T> {
var v = _lookupCache.putIfAbsent(name, () {
var variable = _variables.firstWhereOrNull((v) => v.name == name);
if (variable != null)
if (variable != null) {
return variable;
else if (_parent != null)
} else if (_parent != null) {
return _parent?.resolve(name);
else
} else {
return null;
}
});
if (v == null) {
@ -238,7 +242,7 @@ class SymbolTable<T> {
/// Creates a child scope within this one.
///
/// You may optionally provide starter [values].
SymbolTable<T> createChild({Map<String, T> values: const {}}) {
SymbolTable<T> createChild({Map<String, T> values = const {}}) {
var child = SymbolTable(values: values);
child
.._depth = _depth + 1
@ -273,7 +277,7 @@ class SymbolTable<T> {
/// The forked scope is essentially orphaned and stands alone; although its
/// [parent] getter will point to the parent of the original scope, the parent
/// will not be aware of the new scope's existence.
SymbolTable<T> fork({Map<String, T> values: const {}}) {
SymbolTable<T> fork({Map<String, T> values = const {}}) {
var table = SymbolTable<T>();
table
@ -282,7 +286,7 @@ class SymbolTable<T> {
.._root = _root;
table._variables.addAll(_variables.map((Variable v) {
Variable<T> variable = Variable._(v.name, this, value: v.value);
var variable = Variable<T>._(v.name, this, value: v.value as T?);
variable.visibility = v.visibility;
if (v.isImmutable) variable.lock();
@ -297,7 +301,7 @@ class SymbolTable<T> {
/// The variation will the input [name], but with a numerical suffix appended.
/// Ex. `foo1`, `bar24`
String uniqueName(String name) {
int count = 0;
var count = 0;
SymbolTable? search = this;
while (search != null) {

View file

@ -31,9 +31,10 @@ class Variable<T> {
T? get value => _value;
void set value(T? value) {
if (_locked)
set value(T? value) {
if (_locked) {
throw StateError('The value of constant "$name" cannot be overwritten.');
}
_value = value;
}

View file

@ -13,9 +13,9 @@ part of symbol_table;
///
/// In a nutshell: [private] < [protected] < [public].
class Visibility implements Comparable<Visibility> {
static const Visibility private = const Visibility._(0);
static const Visibility protected = const Visibility._(1);
static const Visibility public = const Visibility._(2);
static const Visibility private = Visibility._(0);
static const Visibility protected = Visibility._(1);
static const Visibility public = Visibility._(2);
final int _n;
const Visibility._(this._n);

View file

@ -1,5 +1,5 @@
name: angel3_symbol_table
version: 2.0.0
version: 2.0.1
description: A generic symbol table implementation in Dart, with support for scopes and constants.
homepage: https://github.com/dukefirehawk/angel/tree/angel3/packages/symbol_table
environment:
@ -8,3 +8,4 @@ dependencies:
collection: ^1.15.0
dev_dependencies:
test: ^1.17.4
pedantic: ^1.11.0