diff --git a/TODO.md b/TODO.md index 6f22267..91d3ce3 100644 --- a/TODO.md +++ b/TODO.md @@ -2,12 +2,13 @@ [x] Means done - [X] Unify error reporting. Create class ErrorHandler that get notified of every catched exception. This class prints the exception in stdout. -- [ ] Make formula description collapsable in FormulaScreen. Initialy, the description is visible, but the user can hide it. +- [X] Make formula description collapsable in FormulaScreen. Initialy, the description is visible, but the user can hide it. - Refactor formula and unit loading: - - [ ] Create method `List parseD4rtLiteral(String arrayStringLiteral). It parses a d4rt array literal (containing maps and arrays) to a List using d4rt - - [ ] Remove `fromArrayStringLiteral` from UnitSpec and Formula. - - [ ] Create function `List parseCorpusElements(String arrayStringLiteral)`. It uses parseD4rtLiteral and determines if each element of the array is a formula or a unit. Then converts the objects with Formula.fromSet or UnitSpec.fromSet. - - [ ] Create method loadFormulaElements( List elements). Tipically receives the list from parseCorpusElements(). It loads the units first, then the formulas, to avoid missing dependencies. + - [X] Create method `List parseD4rtLiteral(String arrayStringLiteral). It parses a d4rt array literal (containing maps and arrays) to a List using d4rt + - [X] Make `fromArrayStringLiteral` from UnitSpec and Formula to use parseD4rtLiteral + - [X] Create function `List parseCorpusElements(String arrayStringLiteral)`. It uses parseD4rtLiteral and determines if each element of the array is a formula or a unit. Then converts the objects with Formula.fromSet or UnitSpec.fromSet. + - [X] Create method loadFormulaElements( List elements). Tipically receives the list from parseCorpusElements(). It loads the units first, then the formulas, to avoid missing dependencies. + - [X] Change createDefaultCorpus to use loadFormulaElements instead of loadUnits and loadFormula. Make loadUnits and loadFormula private. - [ ] Use a single table in database `FORMULAELEMENT` to store formulas and units. The table contains only two columns: autonumeric id and text. - [ ] Create Formula.toStringLiteral. It is the reverse of Formula.fromSet( Formula.fromArrayStringLiteral(string)[0] ) - [ ] Create UnitSpec.toStringLiteral, like Formula.toStringLiteral diff --git a/lib/corpus.dart b/lib/corpus.dart index 8e52e2f..62fcf01 100644 --- a/lib/corpus.dart +++ b/lib/corpus.dart @@ -180,5 +180,28 @@ class Corpus{ Iterable allUnits() => _allUnits.values; + /// Loads formula elements, making sure to load units first, then formulas + /// to avoid dependency issues. + void loadFormulaElements(List elements) { + List units = []; + List formulas = []; + + // Separate units and formulas + for (final element in elements) { + if (element is UnitSpec) { + units.add(element); + } else if (element is Formula) { + formulas.add(element); + } else { + throw ArgumentError('Element must be either UnitSpec or Formula: $element'); + } + } + + // Load units first to satisfy dependencies + loadUnits(units); + + // Then load formulas + loadFormulas(formulas); + } } diff --git a/lib/defaults/default_corpus.dart b/lib/defaults/default_corpus.dart index e6539e9..40f75ec 100644 --- a/lib/defaults/default_corpus.dart +++ b/lib/defaults/default_corpus.dart @@ -39,7 +39,7 @@ Future createDefaultCorpus() async{ print( "Loading units from $unitRes"); final literal = await loadResourceAsString(unitRes); final units = UnitSpec.fromArrayStringLiteral(literal); - corpus.loadUnits(units); + corpus.loadFormulaElements(units); } } @@ -49,7 +49,7 @@ Future createDefaultCorpus() async{ for (final formRes in formulaResources) { final literal = await loadResourceAsString(formRes); final formulas = Formula.fromArrayStringLiteral(literal); - corpus.loadFormulas(formulas); + corpus.loadFormulaElements(formulas); } } diff --git a/lib/formula_models.dart b/lib/formula_models.dart index bff597c..42504a0 100644 --- a/lib/formula_models.dart +++ b/lib/formula_models.dart @@ -23,6 +23,47 @@ abstract class SetUtils { } } +/// Parses a d4rt array literal (containing maps and arrays) to a List +/// using d4rt +List parseD4rtLiteral(String arrayStringLiteral) { + var d4rt = D4rt(); + final buffer = StringBuffer(); + buffer.write("main(){ return $arrayStringLiteral; }"); + final code = buffer.toString(); + + final List list = d4rt.execute(source: code); + + return list; +} + +/// Parses corpus elements from an array string literal. +/// Determines if each element is a formula or a unit and converts accordingly. +List parseCorpusElements(String arrayStringLiteral) { + final List elements = parseD4rtLiteral(arrayStringLiteral); + + final List result = []; + for (final element in elements) { + if (element is Map) { + // Check if it's a formula by looking for required formula properties + // Formulas typically have 'd4rtCode' and 'input'/'output' properties + if (element.containsKey('d4rtCode')) { + result.add(Formula.fromSet(element)); + } + // Units typically have 'name', 'symbol', and 'baseUnit' properties + else if (element.containsKey('name') && element.containsKey('symbol')) { + result.add(UnitSpec.fromSet(element)); + } + else { + throw ArgumentError('Unknown element type: $element'); + } + } else { + throw ArgumentError('Element must be a Map: $element'); + } + } + + return result; +} + typedef Number = double; @@ -86,12 +127,7 @@ class UnitSpec { } static List fromArrayStringLiteral(String arrayStringLiteral) { - var d4rt = D4rt(); - final buffer = StringBuffer(); - buffer.write("main(){ return $arrayStringLiteral; }"); - final code = buffer.toString(); - - final List list = d4rt.execute(source: code); + final List list = parseD4rtLiteral(arrayStringLiteral); final units = list.map((set) => UnitSpec.fromSet(set as Map)); @@ -195,13 +231,7 @@ class Formula { } static List fromArrayStringLiteral(String arrayStringLiteral) { - var d4rt = D4rt(); - final buffer = StringBuffer(); - buffer.write("main(){ return $arrayStringLiteral; }"); - final code = buffer.toString(); - - //print("fromArrayStringLiteral:$code"); - final List list = d4rt.execute(source: code); + final List list = parseD4rtLiteral(arrayStringLiteral); final formulas = list.map((set) => Formula.fromSet(set as Map));