@stevenvo780/st-lang 3.2.3 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -7
- package/dist/api.d.ts +2 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +5 -1
- package/dist/api.js.map +1 -1
- package/dist/argumentation/dot.d.ts +3 -0
- package/dist/argumentation/dot.d.ts.map +1 -0
- package/dist/argumentation/dot.js +25 -0
- package/dist/argumentation/dot.js.map +1 -0
- package/dist/argumentation/extensions.d.ts +11 -0
- package/dist/argumentation/extensions.d.ts.map +1 -0
- package/dist/argumentation/extensions.js +173 -0
- package/dist/argumentation/extensions.js.map +1 -0
- package/dist/argumentation/framework.d.ts +13 -0
- package/dist/argumentation/framework.d.ts.map +1 -0
- package/dist/argumentation/framework.js +117 -0
- package/dist/argumentation/framework.js.map +1 -0
- package/dist/argumentation/index.d.ts +6 -0
- package/dist/argumentation/index.d.ts.map +1 -0
- package/dist/argumentation/index.js +33 -0
- package/dist/argumentation/index.js.map +1 -0
- package/dist/argumentation/types.d.ts +11 -0
- package/dist/argumentation/types.d.ts.map +1 -0
- package/dist/argumentation/types.js +8 -0
- package/dist/argumentation/types.js.map +1 -0
- package/dist/ast/visitor.d.ts +95 -0
- package/dist/ast/visitor.d.ts.map +1 -0
- package/dist/ast/visitor.js +223 -0
- package/dist/ast/visitor.js.map +1 -0
- package/dist/citation-reasoning/derive.d.ts +31 -0
- package/dist/citation-reasoning/derive.d.ts.map +1 -0
- package/dist/citation-reasoning/derive.js +157 -0
- package/dist/citation-reasoning/derive.js.map +1 -0
- package/dist/citation-reasoning/index.d.ts +4 -0
- package/dist/citation-reasoning/index.d.ts.map +1 -0
- package/dist/citation-reasoning/index.js +10 -0
- package/dist/citation-reasoning/index.js.map +1 -0
- package/dist/citation-reasoning/types.d.ts +36 -0
- package/dist/citation-reasoning/types.d.ts.map +1 -0
- package/dist/citation-reasoning/types.js +6 -0
- package/dist/citation-reasoning/types.js.map +1 -0
- package/dist/educational/checker.d.ts +3 -0
- package/dist/educational/checker.d.ts.map +1 -0
- package/dist/educational/checker.js +244 -0
- package/dist/educational/checker.js.map +1 -0
- package/dist/educational/generator.d.ts +4 -0
- package/dist/educational/generator.d.ts.map +1 -0
- package/dist/educational/generator.js +158 -0
- package/dist/educational/generator.js.map +1 -0
- package/dist/educational/index.d.ts +6 -0
- package/dist/educational/index.d.ts.map +1 -0
- package/dist/educational/index.js +21 -0
- package/dist/educational/index.js.map +1 -0
- package/dist/educational/normalize.d.ts +6 -0
- package/dist/educational/normalize.d.ts.map +1 -0
- package/dist/educational/normalize.js +124 -0
- package/dist/educational/normalize.js.map +1 -0
- package/dist/educational/rng.d.ts +10 -0
- package/dist/educational/rng.d.ts.map +1 -0
- package/dist/educational/rng.js +47 -0
- package/dist/educational/rng.js.map +1 -0
- package/dist/educational/templates.d.ts +30 -0
- package/dist/educational/templates.d.ts.map +1 -0
- package/dist/educational/templates.js +567 -0
- package/dist/educational/templates.js.map +1 -0
- package/dist/educational/types.d.ts +44 -0
- package/dist/educational/types.d.ts.map +1 -0
- package/dist/educational/types.js +20 -0
- package/dist/educational/types.js.map +1 -0
- package/dist/exporters/coq/index.d.ts +35 -0
- package/dist/exporters/coq/index.d.ts.map +1 -0
- package/dist/exporters/coq/index.js +299 -0
- package/dist/exporters/coq/index.js.map +1 -0
- package/dist/fol-prover/cnf.d.ts +10 -0
- package/dist/fol-prover/cnf.d.ts.map +1 -0
- package/dist/fol-prover/cnf.js +357 -0
- package/dist/fol-prover/cnf.js.map +1 -0
- package/dist/fol-prover/index.d.ts +7 -0
- package/dist/fol-prover/index.d.ts.map +1 -0
- package/dist/fol-prover/index.js +27 -0
- package/dist/fol-prover/index.js.map +1 -0
- package/dist/fol-prover/prove.d.ts +4 -0
- package/dist/fol-prover/prove.d.ts.map +1 -0
- package/dist/fol-prover/prove.js +34 -0
- package/dist/fol-prover/prove.js.map +1 -0
- package/dist/fol-prover/resolve.d.ts +27 -0
- package/dist/fol-prover/resolve.d.ts.map +1 -0
- package/dist/fol-prover/resolve.js +234 -0
- package/dist/fol-prover/resolve.js.map +1 -0
- package/dist/fol-prover/types.d.ts +34 -0
- package/dist/fol-prover/types.d.ts.map +1 -0
- package/dist/fol-prover/types.js +38 -0
- package/dist/fol-prover/types.js.map +1 -0
- package/dist/fol-prover/unify.d.ts +9 -0
- package/dist/fol-prover/unify.d.ts.map +1 -0
- package/dist/fol-prover/unify.js +110 -0
- package/dist/fol-prover/unify.js.map +1 -0
- package/dist/hyperreal/index.d.ts +45 -0
- package/dist/hyperreal/index.d.ts.map +1 -0
- package/dist/hyperreal/index.js +183 -0
- package/dist/hyperreal/index.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +72 -1
- package/dist/index.js.map +1 -1
- package/dist/lsp/index.d.ts +6 -0
- package/dist/lsp/index.d.ts.map +1 -0
- package/dist/lsp/index.js +29 -0
- package/dist/lsp/index.js.map +1 -0
- package/dist/lsp/protocol.d.ts +20 -0
- package/dist/lsp/protocol.d.ts.map +1 -0
- package/dist/lsp/protocol.js +64 -0
- package/dist/lsp/protocol.js.map +1 -0
- package/dist/lsp/server.d.ts +47 -0
- package/dist/lsp/server.d.ts.map +1 -0
- package/dist/lsp/server.js +529 -0
- package/dist/lsp/server.js.map +1 -0
- package/dist/lsp/types.d.ts +152 -0
- package/dist/lsp/types.d.ts.map +1 -0
- package/dist/lsp/types.js +70 -0
- package/dist/lsp/types.js.map +1 -0
- package/dist/parser/formulas.d.ts +7 -0
- package/dist/parser/formulas.d.ts.map +1 -0
- package/dist/parser/formulas.js +511 -0
- package/dist/parser/formulas.js.map +1 -0
- package/dist/parser/parser.d.ts +11 -41
- package/dist/parser/parser.d.ts.map +1 -1
- package/dist/parser/parser.js +410 -1037
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/state.d.ts +34 -0
- package/dist/parser/state.d.ts.map +1 -0
- package/dist/parser/state.js +163 -0
- package/dist/parser/state.js.map +1 -0
- package/dist/plugin-system/demo-min-logic.d.ts +3 -0
- package/dist/plugin-system/demo-min-logic.d.ts.map +1 -0
- package/dist/plugin-system/demo-min-logic.js +116 -0
- package/dist/plugin-system/demo-min-logic.js.map +1 -0
- package/dist/plugin-system/errors.d.ts +9 -0
- package/dist/plugin-system/errors.d.ts.map +1 -0
- package/dist/plugin-system/errors.js +24 -0
- package/dist/plugin-system/errors.js.map +1 -0
- package/dist/plugin-system/index.d.ts +6 -0
- package/dist/plugin-system/index.d.ts.map +1 -0
- package/dist/plugin-system/index.js +14 -0
- package/dist/plugin-system/index.js.map +1 -0
- package/dist/plugin-system/registry.d.ts +12 -0
- package/dist/plugin-system/registry.d.ts.map +1 -0
- package/dist/plugin-system/registry.js +46 -0
- package/dist/plugin-system/registry.js.map +1 -0
- package/dist/plugin-system/types.d.ts +23 -0
- package/dist/plugin-system/types.d.ts.map +1 -0
- package/dist/plugin-system/types.js +3 -0
- package/dist/plugin-system/types.js.map +1 -0
- package/dist/plugin-system/validate.d.ts +4 -0
- package/dist/plugin-system/validate.d.ts.map +1 -0
- package/dist/plugin-system/validate.js +60 -0
- package/dist/plugin-system/validate.js.map +1 -0
- package/dist/profiles/classical/parallel-sat.js +3 -3
- package/dist/profiles/classical/parallel-sat.js.map +1 -1
- package/dist/proof-exchange/index.d.ts +26 -0
- package/dist/proof-exchange/index.d.ts.map +1 -0
- package/dist/proof-exchange/index.js +94 -0
- package/dist/proof-exchange/index.js.map +1 -0
- package/dist/runtime/memo/cache.d.ts +32 -0
- package/dist/runtime/memo/cache.d.ts.map +1 -0
- package/dist/runtime/memo/cache.js +129 -0
- package/dist/runtime/memo/cache.js.map +1 -0
- package/dist/runtime/memo/hash.d.ts +9 -0
- package/dist/runtime/memo/hash.d.ts.map +1 -0
- package/dist/runtime/memo/hash.js +87 -0
- package/dist/runtime/memo/hash.js.map +1 -0
- package/dist/runtime/memo/index.d.ts +4 -0
- package/dist/runtime/memo/index.d.ts.map +1 -0
- package/dist/runtime/memo/index.js +8 -0
- package/dist/runtime/memo/index.js.map +1 -0
- package/dist/runtime/parallel/index.d.ts +34 -0
- package/dist/runtime/parallel/index.d.ts.map +1 -0
- package/dist/runtime/parallel/index.js +220 -0
- package/dist/runtime/parallel/index.js.map +1 -0
- package/dist/runtime/parallel/worker.d.ts +22 -0
- package/dist/runtime/parallel/worker.d.ts.map +1 -0
- package/dist/runtime/parallel/worker.js +43 -0
- package/dist/runtime/parallel/worker.js.map +1 -0
- package/dist/runtime/smt/index.d.ts +6 -0
- package/dist/runtime/smt/index.d.ts.map +1 -0
- package/dist/runtime/smt/index.js +18 -0
- package/dist/runtime/smt/index.js.map +1 -0
- package/dist/runtime/smt/mock-backend.d.ts +30 -0
- package/dist/runtime/smt/mock-backend.d.ts.map +1 -0
- package/dist/runtime/smt/mock-backend.js +460 -0
- package/dist/runtime/smt/mock-backend.js.map +1 -0
- package/dist/runtime/smt/serializer.d.ts +21 -0
- package/dist/runtime/smt/serializer.d.ts.map +1 -0
- package/dist/runtime/smt/serializer.js +314 -0
- package/dist/runtime/smt/serializer.js.map +1 -0
- package/dist/runtime/smt/subprocess-backend.d.ts +62 -0
- package/dist/runtime/smt/subprocess-backend.d.ts.map +1 -0
- package/dist/runtime/smt/subprocess-backend.js +261 -0
- package/dist/runtime/smt/subprocess-backend.js.map +1 -0
- package/dist/runtime/smt/types.d.ts +57 -0
- package/dist/runtime/smt/types.d.ts.map +1 -0
- package/dist/runtime/smt/types.js +6 -0
- package/dist/runtime/smt/types.js.map +1 -0
- package/dist/runtime/streaming/index.d.ts +4 -0
- package/dist/runtime/streaming/index.d.ts.map +1 -0
- package/dist/runtime/streaming/index.js +9 -0
- package/dist/runtime/streaming/index.js.map +1 -0
- package/dist/runtime/streaming/stream-eval.d.ts +31 -0
- package/dist/runtime/streaming/stream-eval.d.ts.map +1 -0
- package/dist/runtime/streaming/stream-eval.js +155 -0
- package/dist/runtime/streaming/stream-eval.js.map +1 -0
- package/dist/runtime/streaming/types.d.ts +33 -0
- package/dist/runtime/streaming/types.d.ts.map +1 -0
- package/dist/runtime/streaming/types.js +6 -0
- package/dist/runtime/streaming/types.js.map +1 -0
- package/dist/runtime/typecheck/checker.d.ts +72 -0
- package/dist/runtime/typecheck/checker.d.ts.map +1 -0
- package/dist/runtime/typecheck/checker.js +462 -0
- package/dist/runtime/typecheck/checker.js.map +1 -0
- package/dist/runtime/typecheck/index.d.ts +4 -0
- package/dist/runtime/typecheck/index.d.ts.map +1 -0
- package/dist/runtime/typecheck/index.js +13 -0
- package/dist/runtime/typecheck/index.js.map +1 -0
- package/dist/runtime/typecheck/levenshtein.d.ts +11 -0
- package/dist/runtime/typecheck/levenshtein.d.ts.map +1 -0
- package/dist/runtime/typecheck/levenshtein.js +49 -0
- package/dist/runtime/typecheck/levenshtein.js.map +1 -0
- package/dist/runtime/typecheck/types.d.ts +14 -0
- package/dist/runtime/typecheck/types.d.ts.map +1 -0
- package/dist/runtime/typecheck/types.js +26 -0
- package/dist/runtime/typecheck/types.js.map +1 -0
- package/dist/solver/cdcl-v2/clause-learning.d.ts +33 -0
- package/dist/solver/cdcl-v2/clause-learning.d.ts.map +1 -0
- package/dist/solver/cdcl-v2/clause-learning.js +110 -0
- package/dist/solver/cdcl-v2/clause-learning.js.map +1 -0
- package/dist/solver/cdcl-v2/index.d.ts +9 -0
- package/dist/solver/cdcl-v2/index.d.ts.map +1 -0
- package/dist/solver/cdcl-v2/index.js +39 -0
- package/dist/solver/cdcl-v2/index.js.map +1 -0
- package/dist/solver/cdcl-v2/lbd.d.ts +34 -0
- package/dist/solver/cdcl-v2/lbd.d.ts.map +1 -0
- package/dist/solver/cdcl-v2/lbd.js +72 -0
- package/dist/solver/cdcl-v2/lbd.js.map +1 -0
- package/dist/solver/cdcl-v2/luby.d.ts +28 -0
- package/dist/solver/cdcl-v2/luby.d.ts.map +1 -0
- package/dist/solver/cdcl-v2/luby.js +70 -0
- package/dist/solver/cdcl-v2/luby.js.map +1 -0
- package/dist/solver/cdcl-v2/phase-saving.d.ts +14 -0
- package/dist/solver/cdcl-v2/phase-saving.d.ts.map +1 -0
- package/dist/solver/cdcl-v2/phase-saving.js +44 -0
- package/dist/solver/cdcl-v2/phase-saving.js.map +1 -0
- package/dist/solver/cdcl-v2/solver.d.ts +10 -0
- package/dist/solver/cdcl-v2/solver.d.ts.map +1 -0
- package/dist/solver/cdcl-v2/solver.js +442 -0
- package/dist/solver/cdcl-v2/solver.js.map +1 -0
- package/dist/solver/cdcl-v2/state.d.ts +54 -0
- package/dist/solver/cdcl-v2/state.d.ts.map +1 -0
- package/dist/solver/cdcl-v2/state.js +22 -0
- package/dist/solver/cdcl-v2/state.js.map +1 -0
- package/dist/solver/cdcl-v2/vsids.d.ts +19 -0
- package/dist/solver/cdcl-v2/vsids.d.ts.map +1 -0
- package/dist/solver/cdcl-v2/vsids.js +77 -0
- package/dist/solver/cdcl-v2/vsids.js.map +1 -0
- package/dist/tests/agora-integration-fixtures.test.js.map +1 -1
- package/dist/tests/argumentation/dung.test.d.ts +2 -0
- package/dist/tests/argumentation/dung.test.d.ts.map +1 -0
- package/dist/tests/argumentation/dung.test.js +219 -0
- package/dist/tests/argumentation/dung.test.js.map +1 -0
- package/dist/tests/citation-reasoning/citation-reasoning.test.d.ts +2 -0
- package/dist/tests/citation-reasoning/citation-reasoning.test.d.ts.map +1 -0
- package/dist/tests/citation-reasoning/citation-reasoning.test.js +240 -0
- package/dist/tests/citation-reasoning/citation-reasoning.test.js.map +1 -0
- package/dist/tests/coverage-fill-api.test.d.ts +7 -0
- package/dist/tests/coverage-fill-api.test.d.ts.map +1 -0
- package/dist/tests/coverage-fill-api.test.js +310 -0
- package/dist/tests/coverage-fill-api.test.js.map +1 -0
- package/dist/tests/coverage-fill-aristotelian.test.d.ts +7 -0
- package/dist/tests/coverage-fill-aristotelian.test.d.ts.map +1 -0
- package/dist/tests/coverage-fill-aristotelian.test.js +377 -0
- package/dist/tests/coverage-fill-aristotelian.test.js.map +1 -0
- package/dist/tests/coverage-fill-belnap.test.d.ts +6 -0
- package/dist/tests/coverage-fill-belnap.test.d.ts.map +1 -0
- package/dist/tests/coverage-fill-belnap.test.js +277 -0
- package/dist/tests/coverage-fill-belnap.test.js.map +1 -0
- package/dist/tests/coverage-fill-cross-system.test.d.ts +6 -0
- package/dist/tests/coverage-fill-cross-system.test.d.ts.map +1 -0
- package/dist/tests/coverage-fill-cross-system.test.js +75 -0
- package/dist/tests/coverage-fill-cross-system.test.js.map +1 -0
- package/dist/tests/coverage-fill-fallacies.test.d.ts +6 -0
- package/dist/tests/coverage-fill-fallacies.test.d.ts.map +1 -0
- package/dist/tests/coverage-fill-fallacies.test.js +287 -0
- package/dist/tests/coverage-fill-fallacies.test.js.map +1 -0
- package/dist/tests/coverage-fill-format.test.d.ts +7 -0
- package/dist/tests/coverage-fill-format.test.d.ts.map +1 -0
- package/dist/tests/coverage-fill-format.test.js +455 -0
- package/dist/tests/coverage-fill-format.test.js.map +1 -0
- package/dist/tests/coverage-fill-intuitionistic.test.d.ts +6 -0
- package/dist/tests/coverage-fill-intuitionistic.test.d.ts.map +1 -0
- package/dist/tests/coverage-fill-intuitionistic.test.js +293 -0
- package/dist/tests/coverage-fill-intuitionistic.test.js.map +1 -0
- package/dist/tests/coverage-fill-probabilistic.test.d.ts +7 -0
- package/dist/tests/coverage-fill-probabilistic.test.d.ts.map +1 -0
- package/dist/tests/coverage-fill-probabilistic.test.js +314 -0
- package/dist/tests/coverage-fill-probabilistic.test.js.map +1 -0
- package/dist/tests/educational/checker.test.d.ts +2 -0
- package/dist/tests/educational/checker.test.d.ts.map +1 -0
- package/dist/tests/educational/checker.test.js +212 -0
- package/dist/tests/educational/checker.test.js.map +1 -0
- package/dist/tests/educational/generator.test.d.ts +2 -0
- package/dist/tests/educational/generator.test.d.ts.map +1 -0
- package/dist/tests/educational/generator.test.js +137 -0
- package/dist/tests/educational/generator.test.js.map +1 -0
- package/dist/tests/exporters/coq/coq-exporter.test.d.ts +2 -0
- package/dist/tests/exporters/coq/coq-exporter.test.d.ts.map +1 -0
- package/dist/tests/exporters/coq/coq-exporter.test.js +353 -0
- package/dist/tests/exporters/coq/coq-exporter.test.js.map +1 -0
- package/dist/tests/fol-prover/cnf.test.d.ts +2 -0
- package/dist/tests/fol-prover/cnf.test.d.ts.map +1 -0
- package/dist/tests/fol-prover/cnf.test.js +74 -0
- package/dist/tests/fol-prover/cnf.test.js.map +1 -0
- package/dist/tests/fol-prover/prove.test.d.ts +2 -0
- package/dist/tests/fol-prover/prove.test.d.ts.map +1 -0
- package/dist/tests/fol-prover/prove.test.js +106 -0
- package/dist/tests/fol-prover/prove.test.js.map +1 -0
- package/dist/tests/fol-prover/unify.test.d.ts +2 -0
- package/dist/tests/fol-prover/unify.test.d.ts.map +1 -0
- package/dist/tests/fol-prover/unify.test.js +66 -0
- package/dist/tests/fol-prover/unify.test.js.map +1 -0
- package/dist/tests/hyperreal/hyperreal.test.d.ts +2 -0
- package/dist/tests/hyperreal/hyperreal.test.d.ts.map +1 -0
- package/dist/tests/hyperreal/hyperreal.test.js +219 -0
- package/dist/tests/hyperreal/hyperreal.test.js.map +1 -0
- package/dist/tests/lsp/server.test.d.ts +2 -0
- package/dist/tests/lsp/server.test.d.ts.map +1 -0
- package/dist/tests/lsp/server.test.js +406 -0
- package/dist/tests/lsp/server.test.js.map +1 -0
- package/dist/tests/memo/cache.test.d.ts +2 -0
- package/dist/tests/memo/cache.test.d.ts.map +1 -0
- package/dist/tests/memo/cache.test.js +252 -0
- package/dist/tests/memo/cache.test.js.map +1 -0
- package/dist/tests/parallel/parallel-pool.test.d.ts +11 -0
- package/dist/tests/parallel/parallel-pool.test.d.ts.map +1 -0
- package/dist/tests/parallel/parallel-pool.test.js +192 -0
- package/dist/tests/parallel/parallel-pool.test.js.map +1 -0
- package/dist/tests/plugin-system/demo-min-logic.test.d.ts +2 -0
- package/dist/tests/plugin-system/demo-min-logic.test.d.ts.map +1 -0
- package/dist/tests/plugin-system/demo-min-logic.test.js +85 -0
- package/dist/tests/plugin-system/demo-min-logic.test.js.map +1 -0
- package/dist/tests/plugin-system/registry.test.d.ts +2 -0
- package/dist/tests/plugin-system/registry.test.d.ts.map +1 -0
- package/dist/tests/plugin-system/registry.test.js +88 -0
- package/dist/tests/plugin-system/registry.test.js.map +1 -0
- package/dist/tests/plugin-system/validate.test.d.ts +2 -0
- package/dist/tests/plugin-system/validate.test.d.ts.map +1 -0
- package/dist/tests/plugin-system/validate.test.js +101 -0
- package/dist/tests/plugin-system/validate.test.js.map +1 -0
- package/dist/tests/proof-exchange/proof-exchange.test.d.ts +2 -0
- package/dist/tests/proof-exchange/proof-exchange.test.d.ts.map +1 -0
- package/dist/tests/proof-exchange/proof-exchange.test.js +161 -0
- package/dist/tests/proof-exchange/proof-exchange.test.js.map +1 -0
- package/dist/tests/sat-v2/clause-learning.test.d.ts +2 -0
- package/dist/tests/sat-v2/clause-learning.test.d.ts.map +1 -0
- package/dist/tests/sat-v2/clause-learning.test.js +73 -0
- package/dist/tests/sat-v2/clause-learning.test.js.map +1 -0
- package/dist/tests/sat-v2/lbd.test.d.ts +2 -0
- package/dist/tests/sat-v2/lbd.test.d.ts.map +1 -0
- package/dist/tests/sat-v2/lbd.test.js +82 -0
- package/dist/tests/sat-v2/lbd.test.js.map +1 -0
- package/dist/tests/sat-v2/luby.test.d.ts +2 -0
- package/dist/tests/sat-v2/luby.test.d.ts.map +1 -0
- package/dist/tests/sat-v2/luby.test.js +58 -0
- package/dist/tests/sat-v2/luby.test.js.map +1 -0
- package/dist/tests/sat-v2/phase-saving.test.d.ts +2 -0
- package/dist/tests/sat-v2/phase-saving.test.d.ts.map +1 -0
- package/dist/tests/sat-v2/phase-saving.test.js +38 -0
- package/dist/tests/sat-v2/phase-saving.test.js.map +1 -0
- package/dist/tests/sat-v2/solver-end-to-end.test.d.ts +2 -0
- package/dist/tests/sat-v2/solver-end-to-end.test.d.ts.map +1 -0
- package/dist/tests/sat-v2/solver-end-to-end.test.js +199 -0
- package/dist/tests/sat-v2/solver-end-to-end.test.js.map +1 -0
- package/dist/tests/sat-v2/vsids.test.d.ts +2 -0
- package/dist/tests/sat-v2/vsids.test.d.ts.map +1 -0
- package/dist/tests/sat-v2/vsids.test.js +69 -0
- package/dist/tests/sat-v2/vsids.test.js.map +1 -0
- package/dist/tests/smt/mock-backend.test.d.ts +2 -0
- package/dist/tests/smt/mock-backend.test.d.ts.map +1 -0
- package/dist/tests/smt/mock-backend.test.js +129 -0
- package/dist/tests/smt/mock-backend.test.js.map +1 -0
- package/dist/tests/smt/serializer.test.d.ts +2 -0
- package/dist/tests/smt/serializer.test.d.ts.map +1 -0
- package/dist/tests/smt/serializer.test.js +94 -0
- package/dist/tests/smt/serializer.test.js.map +1 -0
- package/dist/tests/smt/subprocess-backend.test.d.ts +2 -0
- package/dist/tests/smt/subprocess-backend.test.d.ts.map +1 -0
- package/dist/tests/smt/subprocess-backend.test.js +89 -0
- package/dist/tests/smt/subprocess-backend.test.js.map +1 -0
- package/dist/tests/streaming/stream-eval.test.d.ts +2 -0
- package/dist/tests/streaming/stream-eval.test.d.ts.map +1 -0
- package/dist/tests/streaming/stream-eval.test.js +170 -0
- package/dist/tests/streaming/stream-eval.test.js.map +1 -0
- package/dist/tests/text-layer-v2/claim-graph.test.d.ts +2 -0
- package/dist/tests/text-layer-v2/claim-graph.test.d.ts.map +1 -0
- package/dist/tests/text-layer-v2/claim-graph.test.js +255 -0
- package/dist/tests/text-layer-v2/claim-graph.test.js.map +1 -0
- package/dist/tests/time-travel/snapshot.test.d.ts +2 -0
- package/dist/tests/time-travel/snapshot.test.d.ts.map +1 -0
- package/dist/tests/time-travel/snapshot.test.js +75 -0
- package/dist/tests/time-travel/snapshot.test.js.map +1 -0
- package/dist/tests/time-travel/store.test.d.ts +2 -0
- package/dist/tests/time-travel/store.test.d.ts.map +1 -0
- package/dist/tests/time-travel/store.test.js +242 -0
- package/dist/tests/time-travel/store.test.js.map +1 -0
- package/dist/tests/typecheck-core.test.d.ts +2 -0
- package/dist/tests/typecheck-core.test.d.ts.map +1 -0
- package/dist/tests/typecheck-core.test.js +339 -0
- package/dist/tests/typecheck-core.test.js.map +1 -0
- package/dist/text-layer/v2/claim-graph.d.ts +45 -0
- package/dist/text-layer/v2/claim-graph.d.ts.map +1 -0
- package/dist/text-layer/v2/claim-graph.js +270 -0
- package/dist/text-layer/v2/claim-graph.js.map +1 -0
- package/dist/text-layer/v2/index.d.ts +6 -0
- package/dist/text-layer/v2/index.d.ts.map +1 -0
- package/dist/text-layer/v2/index.js +10 -0
- package/dist/text-layer/v2/index.js.map +1 -0
- package/dist/text-layer/v2/types.d.ts +32 -0
- package/dist/text-layer/v2/types.d.ts.map +1 -0
- package/dist/text-layer/v2/types.js +11 -0
- package/dist/text-layer/v2/types.js.map +1 -0
- package/dist/time-travel/index.d.ts +4 -0
- package/dist/time-travel/index.d.ts.map +1 -0
- package/dist/time-travel/index.js +8 -0
- package/dist/time-travel/index.js.map +1 -0
- package/dist/time-travel/snapshot.d.ts +9 -0
- package/dist/time-travel/snapshot.d.ts.map +1 -0
- package/dist/time-travel/snapshot.js +24 -0
- package/dist/time-travel/snapshot.js.map +1 -0
- package/dist/time-travel/store.d.ts +14 -0
- package/dist/time-travel/store.d.ts.map +1 -0
- package/dist/time-travel/store.js +119 -0
- package/dist/time-travel/store.js.map +1 -0
- package/dist/time-travel/types.d.ts +50 -0
- package/dist/time-travel/types.d.ts.map +1 -0
- package/dist/time-travel/types.js +3 -0
- package/dist/time-travel/types.js.map +1 -0
- package/package.json +5 -1
package/dist/parser/parser.js
CHANGED
|
@@ -1,57 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* ST Parser — Parser recursivo descendente
|
|
4
|
+
*
|
|
5
|
+
* Refactor α2 (V4): el parser monolitico se descompone en modulos.
|
|
6
|
+
* - ./state.ts — ParserState: token cursor + diagnostico
|
|
7
|
+
* - ./formulas.ts — precedencia de formulas + MODAL_ALIASES + formulaToString
|
|
8
|
+
*
|
|
9
|
+
* La clase `Parser` es el facade publico: misma firma de constructor,
|
|
10
|
+
* mismo `parse(source): Program`, mismo `diagnostics`. Los consumidores
|
|
11
|
+
* (interpreter, cli, api, protocol/handler) NO cambian.
|
|
4
12
|
*/
|
|
5
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
14
|
exports.Parser = void 0;
|
|
7
15
|
const tokens_1 = require("../lexer/tokens");
|
|
8
16
|
const lexer_1 = require("../lexer/lexer");
|
|
9
17
|
const compat_1 = require("../runtime/compat");
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
'deontic.standard': { O: 'box', P: 'diamond', F: 'box_not' },
|
|
13
|
-
'epistemic.s5': { K: 'box', B: 'diamond' },
|
|
14
|
-
'temporal.ltl': { G: 'box', F: 'diamond' },
|
|
15
|
-
'modal.k': { Box: 'box', Dia: 'diamond' },
|
|
16
|
-
'modal.s4': { Box: 'box', Dia: 'diamond' },
|
|
17
|
-
'modal.s5': { Box: 'box', Dia: 'diamond' },
|
|
18
|
-
'modal.t': { Box: 'box', Dia: 'diamond' },
|
|
19
|
-
};
|
|
18
|
+
const state_1 = require("./state");
|
|
19
|
+
const formulas_1 = require("./formulas");
|
|
20
20
|
class Parser {
|
|
21
|
-
|
|
22
|
-
pos = 0;
|
|
23
|
-
file;
|
|
24
|
-
diagnostics = [];
|
|
25
|
-
contextStack = [];
|
|
26
|
-
knownFunctionNames = new Set([
|
|
27
|
-
'typeof',
|
|
28
|
-
'is_valid',
|
|
29
|
-
'is_satisfiable',
|
|
30
|
-
'get_atoms',
|
|
31
|
-
'atoms_of',
|
|
32
|
-
'len',
|
|
33
|
-
'at',
|
|
34
|
-
'formula_eq',
|
|
35
|
-
'input',
|
|
36
|
-
]);
|
|
37
|
-
knownTheoryNames = new Set();
|
|
38
|
-
currentProfile = '';
|
|
21
|
+
state;
|
|
39
22
|
initialProfile;
|
|
40
23
|
constructor(file = '<stdin>', profile) {
|
|
41
|
-
this.
|
|
24
|
+
this.state = new state_1.ParserState(file);
|
|
42
25
|
this.initialProfile = profile;
|
|
43
26
|
}
|
|
27
|
+
// --- Acceso compatible al estado (diagnostics expuesto como antes) ---
|
|
28
|
+
get diagnostics() {
|
|
29
|
+
return this.state.diagnostics;
|
|
30
|
+
}
|
|
31
|
+
set diagnostics(value) {
|
|
32
|
+
this.state.diagnostics = value;
|
|
33
|
+
}
|
|
44
34
|
parse(source) {
|
|
45
35
|
const normalizedSource = (0, compat_1.normalizeSTSource)(source);
|
|
46
|
-
const lexer = new lexer_1.Lexer(normalizedSource, this.file, this.initialProfile);
|
|
47
|
-
this.tokens = lexer.tokenize();
|
|
48
|
-
this.diagnostics.push(...lexer.diagnostics);
|
|
49
|
-
this.pos = 0;
|
|
50
|
-
this.contextStack = [];
|
|
36
|
+
const lexer = new lexer_1.Lexer(normalizedSource, this.state.file, this.initialProfile);
|
|
37
|
+
this.state.tokens = lexer.tokenize();
|
|
38
|
+
this.state.diagnostics.push(...lexer.diagnostics);
|
|
39
|
+
this.state.pos = 0;
|
|
40
|
+
this.state.contextStack = [];
|
|
51
41
|
const statements = [];
|
|
52
|
-
while (!this.isAtEnd()) {
|
|
53
|
-
this.skipNewlines();
|
|
54
|
-
if (this.isAtEnd())
|
|
42
|
+
while (!this.state.isAtEnd()) {
|
|
43
|
+
this.state.skipNewlines();
|
|
44
|
+
if (this.state.isAtEnd())
|
|
55
45
|
break;
|
|
56
46
|
try {
|
|
57
47
|
const stmt = this.parseStatement();
|
|
@@ -61,34 +51,29 @@ class Parser {
|
|
|
61
51
|
}
|
|
62
52
|
catch (e) {
|
|
63
53
|
const message = e instanceof Error ? e.message : 'Error de parseo inesperado';
|
|
64
|
-
this.
|
|
65
|
-
severity: 'error',
|
|
66
|
-
message,
|
|
67
|
-
file: this.file,
|
|
68
|
-
line: this.current().line,
|
|
69
|
-
column: this.current().column,
|
|
70
|
-
});
|
|
54
|
+
this.state.pushDiagnostic('error', message);
|
|
71
55
|
this.advanceToNextStatement();
|
|
72
56
|
}
|
|
73
57
|
}
|
|
74
|
-
return { statements, file: this.file };
|
|
58
|
+
return { statements, file: this.state.file };
|
|
75
59
|
}
|
|
76
60
|
// --- Parsing de statements ---
|
|
77
61
|
parseStatement() {
|
|
78
|
-
const
|
|
62
|
+
const s = this.state;
|
|
63
|
+
const tok = s.current();
|
|
79
64
|
// Detección de llamada a función: nombre(...)
|
|
80
|
-
if (
|
|
81
|
-
(tok.type === tokens_1.TokenType.IDENTIFIER ||
|
|
82
|
-
return
|
|
65
|
+
if (s.peek(1) === tokens_1.TokenType.LPAREN &&
|
|
66
|
+
(tok.type === tokens_1.TokenType.IDENTIFIER || s.knownFunctionNames.has(tok.value))) {
|
|
67
|
+
return s.withContext(`llamada a funcion '${tok.value}'`, () => this.parseFnCall());
|
|
83
68
|
}
|
|
84
69
|
// Detección de llamada a método: objeto.metodo(...)
|
|
85
70
|
if (tok.type === tokens_1.TokenType.IDENTIFIER &&
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return
|
|
71
|
+
s.peek(1) === tokens_1.TokenType.DOT &&
|
|
72
|
+
s.peek(2) === tokens_1.TokenType.IDENTIFIER &&
|
|
73
|
+
s.peek(3) === tokens_1.TokenType.LPAREN) {
|
|
74
|
+
return s.withContext(`llamada a metodo '${tok.value}'`, () => this.parseMemberFnCall());
|
|
90
75
|
}
|
|
91
|
-
return
|
|
76
|
+
return s.withContext(this.describeStatementContext(tok), () => {
|
|
92
77
|
switch (tok.type) {
|
|
93
78
|
case tokens_1.TokenType.LOGIC:
|
|
94
79
|
return this.parseLogicDecl();
|
|
@@ -158,72 +143,76 @@ class Parser {
|
|
|
158
143
|
case tokens_1.TokenType.GLOSSARY:
|
|
159
144
|
return this.parseGlossaryCmd();
|
|
160
145
|
case tokens_1.TokenType.IDENTIFIER:
|
|
161
|
-
throw new Error(
|
|
146
|
+
throw new Error(s.contextualize(`Statement inesperado: '${tok.value}' (${tok.type})`));
|
|
162
147
|
case tokens_1.TokenType.NEWLINE:
|
|
163
|
-
|
|
148
|
+
s.advance();
|
|
164
149
|
return null;
|
|
165
150
|
case tokens_1.TokenType.EOF:
|
|
166
151
|
return null;
|
|
167
152
|
default:
|
|
168
|
-
throw new Error(
|
|
153
|
+
throw new Error(s.contextualize(`Statement inesperado: '${tok.value}' (${tok.type})`));
|
|
169
154
|
}
|
|
170
155
|
});
|
|
171
156
|
}
|
|
172
157
|
// logic classical.propositional
|
|
173
158
|
parseLogicDecl() {
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
let profile =
|
|
178
|
-
while (
|
|
159
|
+
const s = this.state;
|
|
160
|
+
const src = s.loc();
|
|
161
|
+
s.expect(tokens_1.TokenType.LOGIC);
|
|
162
|
+
let profile = s.expectIdent();
|
|
163
|
+
while (s.match(tokens_1.TokenType.DOT)) {
|
|
179
164
|
profile += '.';
|
|
180
|
-
profile +=
|
|
165
|
+
profile += s.expectIdent();
|
|
181
166
|
}
|
|
182
|
-
|
|
167
|
+
s.currentProfile = profile;
|
|
183
168
|
return { kind: 'logic_decl', profile, source: src };
|
|
184
169
|
}
|
|
185
170
|
// axiom name = FORMULA o axiom name : FORMULA
|
|
186
171
|
parseAxiomDecl() {
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
172
|
+
const s = this.state;
|
|
173
|
+
const src = s.loc();
|
|
174
|
+
s.expect(tokens_1.TokenType.AXIOM);
|
|
175
|
+
const name = s.expectIdent();
|
|
176
|
+
s.expectOneOf(tokens_1.TokenType.EQUALS, tokens_1.TokenType.COLON);
|
|
191
177
|
const formula = this.parseFormula();
|
|
192
178
|
return { kind: 'axiom_decl', name, formula, source: src };
|
|
193
179
|
}
|
|
194
180
|
// theorem name = FORMULA o theorem name : FORMULA
|
|
195
181
|
parseTheoremDecl() {
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
182
|
+
const s = this.state;
|
|
183
|
+
const src = s.loc();
|
|
184
|
+
s.expect(tokens_1.TokenType.THEOREM);
|
|
185
|
+
const name = s.expectIdent();
|
|
186
|
+
s.expectOneOf(tokens_1.TokenType.EQUALS, tokens_1.TokenType.COLON);
|
|
200
187
|
const formula = this.parseFormula();
|
|
201
188
|
return { kind: 'theorem_decl', name, formula, source: src };
|
|
202
189
|
}
|
|
203
190
|
// derive FORMULA from {a1, a2, ...}
|
|
204
191
|
parseDeriveCmd() {
|
|
205
|
-
const
|
|
206
|
-
|
|
192
|
+
const s = this.state;
|
|
193
|
+
const src = s.loc();
|
|
194
|
+
s.expect(tokens_1.TokenType.DERIVE);
|
|
207
195
|
const goal = this.parseFormula();
|
|
208
|
-
|
|
209
|
-
const premises =
|
|
196
|
+
s.expect(tokens_1.TokenType.FROM);
|
|
197
|
+
const premises = (0, formulas_1.parseIdList)(s);
|
|
210
198
|
return { kind: 'derive_cmd', goal, premises, source: src };
|
|
211
199
|
}
|
|
212
200
|
// check valid FORMULA | check satisfiable FORMULA | check equivalent F, F
|
|
213
201
|
parseCheckCmd() {
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
202
|
+
const s = this.state;
|
|
203
|
+
const src = s.loc();
|
|
204
|
+
s.expect(tokens_1.TokenType.CHECK);
|
|
205
|
+
if (s.match(tokens_1.TokenType.VALID)) {
|
|
217
206
|
const formula = this.parseFormula();
|
|
218
207
|
return { kind: 'check_valid_cmd', formula, source: src };
|
|
219
208
|
}
|
|
220
|
-
if (
|
|
209
|
+
if (s.match(tokens_1.TokenType.SATISFIABLE)) {
|
|
221
210
|
const formula = this.parseFormula();
|
|
222
211
|
return { kind: 'check_satisfiable_cmd', formula, source: src };
|
|
223
212
|
}
|
|
224
|
-
if (
|
|
213
|
+
if (s.match(tokens_1.TokenType.EQUIVALENT)) {
|
|
225
214
|
const left = this.parseFormula();
|
|
226
|
-
|
|
215
|
+
s.expect(tokens_1.TokenType.COMMA);
|
|
227
216
|
const right = this.parseFormula();
|
|
228
217
|
return { kind: 'check_equivalent_cmd', left, right, source: src };
|
|
229
218
|
}
|
|
@@ -231,98 +220,96 @@ class Parser {
|
|
|
231
220
|
}
|
|
232
221
|
// prove FORMULA [from {a1, a2}]
|
|
233
222
|
parseProveCmd() {
|
|
234
|
-
const
|
|
235
|
-
|
|
223
|
+
const s = this.state;
|
|
224
|
+
const src = s.loc();
|
|
225
|
+
s.expect(tokens_1.TokenType.PROVE);
|
|
236
226
|
const goal = this.parseFormula();
|
|
237
|
-
// 'from' is optional — if omitted, prove from entire theory
|
|
238
227
|
let premises = [];
|
|
239
|
-
if (
|
|
240
|
-
premises =
|
|
228
|
+
if (s.match(tokens_1.TokenType.FROM)) {
|
|
229
|
+
premises = (0, formulas_1.parseIdList)(s);
|
|
241
230
|
}
|
|
242
231
|
return { kind: 'prove_cmd', goal, premises, source: src };
|
|
243
232
|
}
|
|
244
233
|
// countermodel FORMULA | refute FORMULA
|
|
245
234
|
parseCountermodelCmd() {
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
if (
|
|
249
|
-
|
|
235
|
+
const s = this.state;
|
|
236
|
+
const src = s.loc();
|
|
237
|
+
if (s.checkType(tokens_1.TokenType.COUNTERMODEL)) {
|
|
238
|
+
s.advance();
|
|
250
239
|
}
|
|
251
240
|
else {
|
|
252
|
-
|
|
241
|
+
s.expect(tokens_1.TokenType.REFUTE);
|
|
253
242
|
}
|
|
254
243
|
const formula = this.parseFormula();
|
|
255
244
|
return { kind: 'countermodel_cmd', formula, source: src };
|
|
256
245
|
}
|
|
257
246
|
// truth_table FORMULA
|
|
258
247
|
parseTruthTableCmd() {
|
|
259
|
-
const
|
|
260
|
-
|
|
248
|
+
const s = this.state;
|
|
249
|
+
const src = s.loc();
|
|
250
|
+
s.expect(tokens_1.TokenType.TRUTH_TABLE);
|
|
261
251
|
const formula = this.parseFormula();
|
|
262
252
|
return { kind: 'truth_table_cmd', formula, source: src };
|
|
263
253
|
}
|
|
264
254
|
// let name = passage([[path#anchor]])
|
|
265
255
|
// let name = formalize passageName as FORMULA
|
|
266
256
|
parseLetDecl() {
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
257
|
+
const s = this.state;
|
|
258
|
+
const src = s.loc();
|
|
259
|
+
s.expect(tokens_1.TokenType.LET);
|
|
260
|
+
const name = s.expectIdent();
|
|
261
|
+
s.expect(tokens_1.TokenType.EQUALS);
|
|
271
262
|
if (this.canStartActionExpr()) {
|
|
272
263
|
const action = this.parseActionExpr();
|
|
273
264
|
return { kind: 'let_decl', name, letType: 'action', action, source: src };
|
|
274
265
|
}
|
|
275
|
-
if (
|
|
266
|
+
if (s.match(tokens_1.TokenType.PASSAGE)) {
|
|
276
267
|
// passage @Source "text" (standalone passage with source and raw text)
|
|
277
|
-
if (
|
|
278
|
-
|
|
279
|
-
const sourceRef =
|
|
280
|
-
// Optional section: §section or just a string
|
|
268
|
+
if (s.checkType(tokens_1.TokenType.AT)) {
|
|
269
|
+
s.advance(); // skip @
|
|
270
|
+
const sourceRef = s.expectName();
|
|
281
271
|
let section = '';
|
|
282
|
-
if (
|
|
272
|
+
if (s.checkType(tokens_1.TokenType.STRING)) {
|
|
283
273
|
// No section, just text
|
|
284
274
|
}
|
|
285
|
-
else if (
|
|
286
|
-
section =
|
|
287
|
-
|
|
275
|
+
else if (s.checkType(tokens_1.TokenType.IDENTIFIER) || s.checkType(tokens_1.TokenType.NUMBER)) {
|
|
276
|
+
section = s.current().value;
|
|
277
|
+
s.advance();
|
|
288
278
|
}
|
|
289
|
-
if (
|
|
290
|
-
|
|
279
|
+
if (s.checkType(tokens_1.TokenType.STRING)) {
|
|
280
|
+
s.advance();
|
|
291
281
|
const anchorPath = `@${sourceRef}${section ? '#' + section : ''}`;
|
|
292
282
|
return { kind: 'let_decl', name, letType: 'passage', anchorPath, source: src };
|
|
293
283
|
}
|
|
294
284
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
// El lexer ya leyó el contenido como STRING entre [[ y ]]
|
|
285
|
+
s.expect(tokens_1.TokenType.LPAREN);
|
|
286
|
+
s.expect(tokens_1.TokenType.LBRACKET_DOUBLE);
|
|
298
287
|
let anchorPath = '';
|
|
299
|
-
if (
|
|
300
|
-
anchorPath =
|
|
301
|
-
|
|
288
|
+
if (s.checkType(tokens_1.TokenType.STRING)) {
|
|
289
|
+
anchorPath = s.current().value;
|
|
290
|
+
s.advance();
|
|
302
291
|
}
|
|
303
292
|
else {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
this.advance();
|
|
293
|
+
while (!s.checkType(tokens_1.TokenType.RBRACKET_DOUBLE) && !s.isAtEnd()) {
|
|
294
|
+
anchorPath += s.current().value;
|
|
295
|
+
s.advance();
|
|
308
296
|
}
|
|
309
297
|
}
|
|
310
|
-
|
|
311
|
-
|
|
298
|
+
s.expect(tokens_1.TokenType.RBRACKET_DOUBLE);
|
|
299
|
+
s.expect(tokens_1.TokenType.RPAREN);
|
|
312
300
|
return { kind: 'let_decl', name, letType: 'passage', anchorPath, source: src };
|
|
313
301
|
}
|
|
314
|
-
if (
|
|
315
|
-
const passageName =
|
|
316
|
-
|
|
302
|
+
if (s.match(tokens_1.TokenType.FORMALIZE)) {
|
|
303
|
+
const passageName = s.expectIdent();
|
|
304
|
+
s.expect(tokens_1.TokenType.AS);
|
|
317
305
|
const formula = this.parseFormula();
|
|
318
306
|
return { kind: 'let_decl', name, letType: 'formalize', passageName, formula, source: src };
|
|
319
307
|
}
|
|
320
308
|
// let name = "texto descriptivo" [: FORMULA]
|
|
321
|
-
if (
|
|
322
|
-
const description =
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
if (this.match(tokens_1.TokenType.COLON)) {
|
|
309
|
+
if (s.checkType(tokens_1.TokenType.STRING)) {
|
|
310
|
+
const description = s.current().value;
|
|
311
|
+
s.advance();
|
|
312
|
+
if (s.match(tokens_1.TokenType.COLON)) {
|
|
326
313
|
const formula = this.parseFormula();
|
|
327
314
|
return { kind: 'let_decl', name, letType: 'formula', formula, description, source: src };
|
|
328
315
|
}
|
|
@@ -334,192 +321,194 @@ class Parser {
|
|
|
334
321
|
}
|
|
335
322
|
// claim name = ID_OR_FORMULA
|
|
336
323
|
parseClaimDecl() {
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
// Si después del IDENTIFIER hay un NEWLINE o EOF, es una referencia.
|
|
348
|
-
if (this.isAtEnd() || this.checkType(tokens_1.TokenType.NEWLINE)) {
|
|
324
|
+
const s = this.state;
|
|
325
|
+
const src = s.loc();
|
|
326
|
+
s.expect(tokens_1.TokenType.CLAIM);
|
|
327
|
+
const name = s.expectIdent();
|
|
328
|
+
s.expect(tokens_1.TokenType.EQUALS);
|
|
329
|
+
if (s.checkType(tokens_1.TokenType.IDENTIFIER) && s.peek(1) !== tokens_1.TokenType.LPAREN) {
|
|
330
|
+
const val = s.current().value;
|
|
331
|
+
const saved = s.pos;
|
|
332
|
+
s.advance();
|
|
333
|
+
if (s.isAtEnd() || s.checkType(tokens_1.TokenType.NEWLINE)) {
|
|
349
334
|
return { kind: 'claim_decl', name, value: val, formalization: val, source: src };
|
|
350
335
|
}
|
|
351
|
-
|
|
352
|
-
this.pos = saved;
|
|
336
|
+
s.pos = saved;
|
|
353
337
|
}
|
|
354
338
|
const formula = this.parseFormula();
|
|
355
339
|
return {
|
|
356
340
|
kind: 'claim_decl',
|
|
357
341
|
name,
|
|
358
|
-
value:
|
|
342
|
+
value: (0, formulas_1.formulaToString)(formula),
|
|
359
343
|
formula,
|
|
360
344
|
source: src,
|
|
361
345
|
};
|
|
362
346
|
}
|
|
363
347
|
// support claimName <- sourceName
|
|
364
348
|
parseSupportDecl() {
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
349
|
+
const s = this.state;
|
|
350
|
+
const src = s.loc();
|
|
351
|
+
s.expect(tokens_1.TokenType.SUPPORT);
|
|
352
|
+
const claimName = s.expectIdent();
|
|
353
|
+
s.expect(tokens_1.TokenType.BACK_ARROW);
|
|
354
|
+
const sourceName = s.expectIdent();
|
|
370
355
|
return { kind: 'support_decl', claimName, sourceName, source: src };
|
|
371
356
|
}
|
|
372
357
|
// confidence claimName = NUMBER
|
|
373
358
|
parseConfidenceDecl() {
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
359
|
+
const s = this.state;
|
|
360
|
+
const src = s.loc();
|
|
361
|
+
s.expect(tokens_1.TokenType.CONFIDENCE);
|
|
362
|
+
const claimName = s.expectIdent();
|
|
363
|
+
s.expect(tokens_1.TokenType.EQUALS);
|
|
364
|
+
const tok = s.expect(tokens_1.TokenType.NUMBER);
|
|
379
365
|
return { kind: 'confidence_decl', claimName, value: parseFloat(tok.value), source: src };
|
|
380
366
|
}
|
|
381
367
|
// context claimName = "text"
|
|
382
368
|
parseContextDecl() {
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
369
|
+
const s = this.state;
|
|
370
|
+
const src = s.loc();
|
|
371
|
+
s.expect(tokens_1.TokenType.CONTEXT);
|
|
372
|
+
const claimName = s.expectIdent();
|
|
373
|
+
s.expect(tokens_1.TokenType.EQUALS);
|
|
374
|
+
const tok = s.expect(tokens_1.TokenType.STRING);
|
|
388
375
|
return { kind: 'context_decl', claimName, text: tok.value, source: src };
|
|
389
376
|
}
|
|
390
377
|
// render target [as FORMAT] | render glossary [as FORMAT] | render analysis [as FORMAT]
|
|
391
378
|
parseRenderCmd() {
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
379
|
+
const s = this.state;
|
|
380
|
+
const src = s.loc();
|
|
381
|
+
s.expect(tokens_1.TokenType.RENDER);
|
|
395
382
|
let target;
|
|
396
|
-
if (
|
|
397
|
-
target =
|
|
398
|
-
|
|
383
|
+
if (s.checkType(tokens_1.TokenType.THEORY)) {
|
|
384
|
+
target = s.current().value;
|
|
385
|
+
s.advance();
|
|
399
386
|
}
|
|
400
|
-
else if (
|
|
387
|
+
else if (s.checkType(tokens_1.TokenType.GLOSSARY)) {
|
|
401
388
|
target = 'glossary';
|
|
402
|
-
|
|
389
|
+
s.advance();
|
|
403
390
|
}
|
|
404
391
|
else {
|
|
405
|
-
target =
|
|
392
|
+
target = s.expectIdent();
|
|
406
393
|
}
|
|
407
394
|
let format = 'markdown';
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
this.advance();
|
|
395
|
+
if (s.match(tokens_1.TokenType.AS)) {
|
|
396
|
+
if (s.checkType(tokens_1.TokenType.IDENTIFIER)) {
|
|
397
|
+
format = s.current().value;
|
|
398
|
+
s.advance();
|
|
413
399
|
}
|
|
414
400
|
}
|
|
415
|
-
else if (
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
this.advance();
|
|
401
|
+
else if (s.checkType(tokens_1.TokenType.IDENTIFIER)) {
|
|
402
|
+
format = s.current().value;
|
|
403
|
+
s.advance();
|
|
419
404
|
}
|
|
420
405
|
return { kind: 'render_cmd', target, format, source: src };
|
|
421
406
|
}
|
|
422
407
|
// analyze {P1, P2, ...} -> CONCLUSION
|
|
423
408
|
parseAnalyzeCmd() {
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
|
|
409
|
+
const s = this.state;
|
|
410
|
+
const src = s.loc();
|
|
411
|
+
s.expect(tokens_1.TokenType.ANALYZE);
|
|
412
|
+
s.expect(tokens_1.TokenType.LBRACE);
|
|
427
413
|
const premises = [];
|
|
428
|
-
if (!
|
|
414
|
+
if (!s.checkType(tokens_1.TokenType.RBRACE)) {
|
|
429
415
|
premises.push(this.parseFormula());
|
|
430
|
-
while (
|
|
416
|
+
while (s.match(tokens_1.TokenType.COMMA)) {
|
|
431
417
|
premises.push(this.parseFormula());
|
|
432
418
|
}
|
|
433
419
|
}
|
|
434
|
-
|
|
435
|
-
|
|
420
|
+
s.expect(tokens_1.TokenType.RBRACE);
|
|
421
|
+
s.expect(tokens_1.TokenType.ARROW);
|
|
436
422
|
const conclusion = this.parseFormula();
|
|
437
423
|
return { kind: 'analyze_cmd', premises, conclusion, source: src };
|
|
438
424
|
}
|
|
439
425
|
// explain FORMULA
|
|
440
426
|
parseExplainCmd() {
|
|
441
|
-
const
|
|
442
|
-
|
|
427
|
+
const s = this.state;
|
|
428
|
+
const src = s.loc();
|
|
429
|
+
s.expect(tokens_1.TokenType.EXPLAIN);
|
|
443
430
|
const formula = this.parseFormula();
|
|
444
431
|
return { kind: 'explain_cmd', formula, source: src };
|
|
445
432
|
}
|
|
446
433
|
canStartActionExpr() {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
434
|
+
const s = this.state;
|
|
435
|
+
return (s.checkType(tokens_1.TokenType.CHECK) ||
|
|
436
|
+
s.checkType(tokens_1.TokenType.DERIVE) ||
|
|
437
|
+
s.checkType(tokens_1.TokenType.PROVE) ||
|
|
438
|
+
s.checkType(tokens_1.TokenType.COUNTERMODEL) ||
|
|
439
|
+
s.checkType(tokens_1.TokenType.REFUTE) ||
|
|
440
|
+
s.checkType(tokens_1.TokenType.TRUTH_TABLE) ||
|
|
441
|
+
s.checkType(tokens_1.TokenType.EXPLAIN));
|
|
454
442
|
}
|
|
455
443
|
parseActionExpr() {
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
|
|
444
|
+
const s = this.state;
|
|
445
|
+
const src = s.loc();
|
|
446
|
+
if (s.match(tokens_1.TokenType.CHECK)) {
|
|
447
|
+
if (s.match(tokens_1.TokenType.VALID)) {
|
|
459
448
|
const formula = this.parseFormula();
|
|
460
449
|
return { kind: 'action_expr', action: 'check_valid', formula, source: src };
|
|
461
450
|
}
|
|
462
|
-
if (
|
|
451
|
+
if (s.match(tokens_1.TokenType.SATISFIABLE)) {
|
|
463
452
|
const formula = this.parseFormula();
|
|
464
453
|
return { kind: 'action_expr', action: 'check_satisfiable', formula, source: src };
|
|
465
454
|
}
|
|
466
|
-
if (
|
|
455
|
+
if (s.match(tokens_1.TokenType.EQUIVALENT)) {
|
|
467
456
|
const left = this.parseFormula();
|
|
468
|
-
|
|
457
|
+
s.expect(tokens_1.TokenType.COMMA);
|
|
469
458
|
const right = this.parseFormula();
|
|
470
459
|
return { kind: 'action_expr', action: 'check_equivalent', left, right, source: src };
|
|
471
460
|
}
|
|
472
461
|
throw new Error(`Se esperaba 'valid', 'satisfiable' o 'equivalent' despues de 'check'`);
|
|
473
462
|
}
|
|
474
|
-
if (
|
|
463
|
+
if (s.match(tokens_1.TokenType.DERIVE)) {
|
|
475
464
|
const goal = this.parseFormula();
|
|
476
|
-
|
|
477
|
-
const premises =
|
|
465
|
+
s.expect(tokens_1.TokenType.FROM);
|
|
466
|
+
const premises = (0, formulas_1.parseIdList)(s);
|
|
478
467
|
return { kind: 'action_expr', action: 'derive', goal, premises, source: src };
|
|
479
468
|
}
|
|
480
|
-
if (
|
|
469
|
+
if (s.match(tokens_1.TokenType.PROVE)) {
|
|
481
470
|
const goal = this.parseFormula();
|
|
482
|
-
|
|
483
|
-
const premises =
|
|
471
|
+
s.expect(tokens_1.TokenType.FROM);
|
|
472
|
+
const premises = (0, formulas_1.parseIdList)(s);
|
|
484
473
|
return { kind: 'action_expr', action: 'prove', goal, premises, source: src };
|
|
485
474
|
}
|
|
486
|
-
if (
|
|
487
|
-
|
|
475
|
+
if (s.checkType(tokens_1.TokenType.COUNTERMODEL)) {
|
|
476
|
+
s.advance();
|
|
488
477
|
const formula = this.parseFormula();
|
|
489
478
|
return { kind: 'action_expr', action: 'countermodel', formula, source: src };
|
|
490
479
|
}
|
|
491
|
-
if (
|
|
480
|
+
if (s.match(tokens_1.TokenType.REFUTE)) {
|
|
492
481
|
const formula = this.parseFormula();
|
|
493
482
|
return { kind: 'action_expr', action: 'countermodel', formula, source: src };
|
|
494
483
|
}
|
|
495
|
-
if (
|
|
484
|
+
if (s.match(tokens_1.TokenType.TRUTH_TABLE)) {
|
|
496
485
|
const formula = this.parseFormula();
|
|
497
486
|
return { kind: 'action_expr', action: 'truth_table', formula, source: src };
|
|
498
487
|
}
|
|
499
|
-
if (
|
|
488
|
+
if (s.match(tokens_1.TokenType.EXPLAIN)) {
|
|
500
489
|
const formula = this.parseFormula();
|
|
501
490
|
return { kind: 'action_expr', action: 'explain', formula, source: src };
|
|
502
491
|
}
|
|
503
|
-
throw new Error(`Se esperaba una acción capturable, encontrado '${
|
|
492
|
+
throw new Error(`Se esperaba una acción capturable, encontrado '${s.current().value}'`);
|
|
504
493
|
}
|
|
505
494
|
// import "path/to/file.st" | import path/to/file
|
|
506
495
|
parseImportDecl() {
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
496
|
+
const s = this.state;
|
|
497
|
+
const src = s.loc();
|
|
498
|
+
s.expect(tokens_1.TokenType.IMPORT);
|
|
510
499
|
let path;
|
|
511
|
-
if (
|
|
512
|
-
path =
|
|
513
|
-
|
|
500
|
+
if (s.checkType(tokens_1.TokenType.STRING)) {
|
|
501
|
+
path = s.current().value;
|
|
502
|
+
s.advance();
|
|
514
503
|
}
|
|
515
504
|
else {
|
|
516
|
-
path =
|
|
517
|
-
while (
|
|
518
|
-
if (
|
|
505
|
+
path = s.expectIdent();
|
|
506
|
+
while (s.checkType(tokens_1.TokenType.DOT) || s.checkType(tokens_1.TokenType.IDENTIFIER)) {
|
|
507
|
+
if (s.match(tokens_1.TokenType.DOT)) {
|
|
519
508
|
path += '.';
|
|
520
|
-
if (
|
|
521
|
-
path +=
|
|
522
|
-
|
|
509
|
+
if (s.checkType(tokens_1.TokenType.IDENTIFIER)) {
|
|
510
|
+
path += s.current().value;
|
|
511
|
+
s.advance();
|
|
523
512
|
}
|
|
524
513
|
}
|
|
525
514
|
else {
|
|
@@ -531,85 +520,73 @@ class Parser {
|
|
|
531
520
|
}
|
|
532
521
|
// assume name : FORMULA\n ... \n show FORMULA\n ... \n qed
|
|
533
522
|
parseProofBlock() {
|
|
534
|
-
const
|
|
523
|
+
const s = this.state;
|
|
524
|
+
const src = s.loc();
|
|
535
525
|
const assumptions = [];
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
this.expectOneOf(tokens_1.TokenType.COLON, tokens_1.TokenType.EQUALS);
|
|
526
|
+
while (s.checkType(tokens_1.TokenType.ASSUME)) {
|
|
527
|
+
s.advance();
|
|
528
|
+
const name = s.expectIdent();
|
|
529
|
+
s.expectOneOf(tokens_1.TokenType.COLON, tokens_1.TokenType.EQUALS);
|
|
541
530
|
const formula = this.parseFormula();
|
|
542
531
|
assumptions.push({ name, formula });
|
|
543
|
-
|
|
532
|
+
s.skipNewlines();
|
|
544
533
|
}
|
|
545
|
-
|
|
546
|
-
this.expect(tokens_1.TokenType.SHOW);
|
|
534
|
+
s.expect(tokens_1.TokenType.SHOW);
|
|
547
535
|
const goal = this.parseFormula();
|
|
548
|
-
|
|
549
|
-
// Parsear body statements hasta 'qed'
|
|
536
|
+
s.skipNewlines();
|
|
550
537
|
const body = [];
|
|
551
|
-
while (!
|
|
552
|
-
|
|
553
|
-
if (
|
|
538
|
+
while (!s.checkType(tokens_1.TokenType.QED) && !s.isAtEnd()) {
|
|
539
|
+
s.skipNewlines();
|
|
540
|
+
if (s.checkType(tokens_1.TokenType.QED))
|
|
554
541
|
break;
|
|
555
542
|
try {
|
|
556
|
-
const stmt =
|
|
557
|
-
? this.parseProofBlock()
|
|
558
|
-
: this.parseStatement();
|
|
543
|
+
const stmt = s.checkType(tokens_1.TokenType.ASSUME) ? this.parseProofBlock() : this.parseStatement();
|
|
559
544
|
if (stmt)
|
|
560
545
|
body.push(stmt);
|
|
561
546
|
}
|
|
562
547
|
catch (e) {
|
|
563
548
|
const message = e instanceof Error ? e.message : 'Error de parseo en bloque de prueba';
|
|
564
|
-
|
|
565
|
-
severity: 'error',
|
|
566
|
-
message,
|
|
567
|
-
file: this.file,
|
|
568
|
-
line: this.current().line,
|
|
569
|
-
column: this.current().column,
|
|
570
|
-
});
|
|
549
|
+
s.pushDiagnostic('error', message);
|
|
571
550
|
this.advanceToNextStatement();
|
|
572
551
|
}
|
|
573
552
|
}
|
|
574
|
-
if (
|
|
553
|
+
if (s.isAtEnd()) {
|
|
575
554
|
throw new Error(`Se esperaba 'qed' para cerrar el bloque de prueba abierto en linea ${src.line}, columna ${src.column}`);
|
|
576
555
|
}
|
|
577
|
-
|
|
556
|
+
s.expect(tokens_1.TokenType.QED);
|
|
578
557
|
return { kind: 'proof_block', assumptions, goal, body, source: src };
|
|
579
558
|
}
|
|
580
559
|
// theory Name(params) { ... } | theory Name extends Parent { ... }
|
|
581
560
|
parseTheoryDecl() {
|
|
582
|
-
const
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
561
|
+
const s = this.state;
|
|
562
|
+
const src = s.loc();
|
|
563
|
+
s.expect(tokens_1.TokenType.THEORY);
|
|
564
|
+
const name = s.expectName();
|
|
565
|
+
s.knownTheoryNames.add(name);
|
|
587
566
|
let params;
|
|
588
|
-
if (
|
|
567
|
+
if (s.match(tokens_1.TokenType.LPAREN)) {
|
|
589
568
|
params = [];
|
|
590
|
-
if (!
|
|
591
|
-
params.push(
|
|
592
|
-
while (
|
|
593
|
-
params.push(
|
|
569
|
+
if (!s.checkType(tokens_1.TokenType.RPAREN)) {
|
|
570
|
+
params.push(s.expectName());
|
|
571
|
+
while (s.match(tokens_1.TokenType.COMMA)) {
|
|
572
|
+
params.push(s.expectName());
|
|
594
573
|
}
|
|
595
574
|
}
|
|
596
|
-
|
|
575
|
+
s.expect(tokens_1.TokenType.RPAREN);
|
|
597
576
|
}
|
|
598
|
-
// Herencia opcional: extends Parent
|
|
599
577
|
let parent;
|
|
600
|
-
if (
|
|
601
|
-
parent =
|
|
578
|
+
if (s.match(tokens_1.TokenType.EXTENDS)) {
|
|
579
|
+
parent = s.expectName();
|
|
602
580
|
}
|
|
603
|
-
|
|
604
|
-
|
|
581
|
+
s.expect(tokens_1.TokenType.LBRACE);
|
|
582
|
+
s.skipNewlines();
|
|
605
583
|
const members = [];
|
|
606
|
-
while (!
|
|
607
|
-
|
|
608
|
-
if (
|
|
584
|
+
while (!s.checkType(tokens_1.TokenType.RBRACE) && !s.isAtEnd()) {
|
|
585
|
+
s.skipNewlines();
|
|
586
|
+
if (s.checkType(tokens_1.TokenType.RBRACE))
|
|
609
587
|
break;
|
|
610
|
-
// Visibilidad: private/privado o public (default)
|
|
611
588
|
let visibility = 'public';
|
|
612
|
-
if (
|
|
589
|
+
if (s.match(tokens_1.TokenType.PRIVATE)) {
|
|
613
590
|
visibility = 'private';
|
|
614
591
|
}
|
|
615
592
|
try {
|
|
@@ -620,70 +597,62 @@ class Parser {
|
|
|
620
597
|
}
|
|
621
598
|
catch (e) {
|
|
622
599
|
const message = e instanceof Error ? e.message : 'Error de parseo en theory';
|
|
623
|
-
|
|
624
|
-
severity: 'error',
|
|
625
|
-
message,
|
|
626
|
-
file: this.file,
|
|
627
|
-
line: this.current().line,
|
|
628
|
-
column: this.current().column,
|
|
629
|
-
});
|
|
600
|
+
s.pushDiagnostic('error', message);
|
|
630
601
|
this.advanceToNextStatement();
|
|
631
602
|
}
|
|
632
603
|
}
|
|
633
|
-
|
|
604
|
+
s.expect(tokens_1.TokenType.RBRACE);
|
|
634
605
|
return { kind: 'theory_decl', name, params, parent, members, source: src };
|
|
635
606
|
}
|
|
636
607
|
// --- print "texto" | print formula ---
|
|
637
608
|
parsePrintCmd() {
|
|
638
|
-
const
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
609
|
+
const s = this.state;
|
|
610
|
+
const src = s.loc();
|
|
611
|
+
s.expect(tokens_1.TokenType.PRINT);
|
|
612
|
+
if (s.checkType(tokens_1.TokenType.STRING)) {
|
|
613
|
+
const value = s.current().value;
|
|
614
|
+
s.advance();
|
|
643
615
|
return { kind: 'print_cmd', value, source: src };
|
|
644
616
|
}
|
|
645
|
-
// Imprimir resultado de fórmula
|
|
646
617
|
const formula = this.parseFormula();
|
|
647
618
|
return { kind: 'print_cmd', value: null, formula, source: src };
|
|
648
619
|
}
|
|
649
620
|
// --- set x = formula ---
|
|
650
621
|
parseSetCmd() {
|
|
651
|
-
const
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
622
|
+
const s = this.state;
|
|
623
|
+
const src = s.loc();
|
|
624
|
+
s.expect(tokens_1.TokenType.SET);
|
|
625
|
+
const name = s.expectName();
|
|
626
|
+
s.expectOneOf(tokens_1.TokenType.EQUALS, tokens_1.TokenType.COLON);
|
|
655
627
|
const formula = this.parseFormula();
|
|
656
628
|
return { kind: 'set_cmd', name, formula, source: src };
|
|
657
629
|
}
|
|
658
630
|
// --- if valid FORMULA { } else if satisfiable FORMULA { } else { } ---
|
|
659
631
|
parseIfStmt() {
|
|
660
|
-
const
|
|
632
|
+
const s = this.state;
|
|
633
|
+
const src = s.loc();
|
|
661
634
|
const branches = [];
|
|
662
635
|
let elseBranch;
|
|
663
|
-
|
|
664
|
-
this.expect(tokens_1.TokenType.IF);
|
|
636
|
+
s.expect(tokens_1.TokenType.IF);
|
|
665
637
|
branches.push(this.parseConditionBranch());
|
|
666
|
-
// Ramas else if
|
|
667
638
|
while (this.checkElseIf()) {
|
|
668
|
-
|
|
669
|
-
|
|
639
|
+
s.expect(tokens_1.TokenType.ELSE);
|
|
640
|
+
s.expect(tokens_1.TokenType.IF);
|
|
670
641
|
branches.push(this.parseConditionBranch());
|
|
671
642
|
}
|
|
672
|
-
|
|
673
|
-
if (this.match(tokens_1.TokenType.ELSE)) {
|
|
643
|
+
if (s.match(tokens_1.TokenType.ELSE)) {
|
|
674
644
|
elseBranch = this.parseBlock();
|
|
675
645
|
}
|
|
676
646
|
return { kind: 'if_stmt', branches, elseBranch, source: src };
|
|
677
647
|
}
|
|
678
648
|
checkElseIf() {
|
|
679
|
-
|
|
680
|
-
if (!
|
|
649
|
+
const s = this.state;
|
|
650
|
+
if (!s.checkType(tokens_1.TokenType.ELSE))
|
|
681
651
|
return false;
|
|
682
|
-
// Buscar if después de else (puede haber newlines)
|
|
683
652
|
let lookahead = 1;
|
|
684
|
-
while (
|
|
653
|
+
while (s.peek(lookahead) === tokens_1.TokenType.NEWLINE)
|
|
685
654
|
lookahead++;
|
|
686
|
-
return
|
|
655
|
+
return s.peek(lookahead) === tokens_1.TokenType.IF;
|
|
687
656
|
}
|
|
688
657
|
parseConditionBranch() {
|
|
689
658
|
const condition = this.parseConditionKeyword();
|
|
@@ -692,46 +661,48 @@ class Parser {
|
|
|
692
661
|
return { condition, formula, body };
|
|
693
662
|
}
|
|
694
663
|
parseConditionKeyword() {
|
|
695
|
-
|
|
664
|
+
const s = this.state;
|
|
665
|
+
if (s.match(tokens_1.TokenType.VALID))
|
|
696
666
|
return 'valid';
|
|
697
|
-
if (
|
|
667
|
+
if (s.match(tokens_1.TokenType.SATISFIABLE))
|
|
698
668
|
return 'satisfiable';
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
const v = this.current().value.toLowerCase();
|
|
669
|
+
if (s.checkType(tokens_1.TokenType.IDENTIFIER)) {
|
|
670
|
+
const v = s.current().value.toLowerCase();
|
|
702
671
|
if (v === 'invalid' || v === 'invalido') {
|
|
703
|
-
|
|
672
|
+
s.advance();
|
|
704
673
|
return 'invalid';
|
|
705
674
|
}
|
|
706
675
|
if (v === 'unsatisfiable' || v === 'insatisfacible') {
|
|
707
|
-
|
|
676
|
+
s.advance();
|
|
708
677
|
return 'unsatisfiable';
|
|
709
678
|
}
|
|
710
679
|
}
|
|
711
|
-
throw new Error(
|
|
680
|
+
throw new Error(s.contextualize(`Se esperaba una condición lógica ('valid', 'satisfiable', 'invalid' o 'unsatisfiable'), encontrado '${s.current().value}'`));
|
|
712
681
|
}
|
|
713
682
|
// --- for x in {A, B, C} { body } ---
|
|
714
683
|
parseForStmt() {
|
|
715
|
-
const
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
684
|
+
const s = this.state;
|
|
685
|
+
const src = s.loc();
|
|
686
|
+
s.expect(tokens_1.TokenType.FOR);
|
|
687
|
+
const variable = s.expectName();
|
|
688
|
+
s.expect(tokens_1.TokenType.IN);
|
|
689
|
+
s.expect(tokens_1.TokenType.LBRACE);
|
|
720
690
|
const items = [];
|
|
721
|
-
if (!
|
|
691
|
+
if (!s.checkType(tokens_1.TokenType.RBRACE)) {
|
|
722
692
|
items.push(this.parseFormula());
|
|
723
|
-
while (
|
|
693
|
+
while (s.match(tokens_1.TokenType.COMMA)) {
|
|
724
694
|
items.push(this.parseFormula());
|
|
725
695
|
}
|
|
726
696
|
}
|
|
727
|
-
|
|
697
|
+
s.expect(tokens_1.TokenType.RBRACE);
|
|
728
698
|
const body = this.parseBlock();
|
|
729
699
|
return { kind: 'for_stmt', variable, items, body, source: src };
|
|
730
700
|
}
|
|
731
701
|
// --- while valid FORMULA { body } ---
|
|
732
702
|
parseWhileStmt() {
|
|
733
|
-
const
|
|
734
|
-
|
|
703
|
+
const s = this.state;
|
|
704
|
+
const src = s.loc();
|
|
705
|
+
s.expect(tokens_1.TokenType.WHILE);
|
|
735
706
|
const condition = this.parseConditionKeyword();
|
|
736
707
|
const formula = this.parseFormula();
|
|
737
708
|
const body = this.parseBlock();
|
|
@@ -739,44 +710,45 @@ class Parser {
|
|
|
739
710
|
}
|
|
740
711
|
// --- fn nombre(param1, param2) { body } ---
|
|
741
712
|
parseFnDecl() {
|
|
742
|
-
const
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
713
|
+
const s = this.state;
|
|
714
|
+
const src = s.loc();
|
|
715
|
+
s.expect(tokens_1.TokenType.FN);
|
|
716
|
+
const name = s.expectName();
|
|
717
|
+
s.knownFunctionNames.add(name);
|
|
718
|
+
s.expect(tokens_1.TokenType.LPAREN);
|
|
747
719
|
const params = [];
|
|
748
|
-
if (!
|
|
749
|
-
params.push(
|
|
750
|
-
while (
|
|
751
|
-
params.push(
|
|
720
|
+
if (!s.checkType(tokens_1.TokenType.RPAREN)) {
|
|
721
|
+
params.push(s.expectName());
|
|
722
|
+
while (s.match(tokens_1.TokenType.COMMA)) {
|
|
723
|
+
params.push(s.expectName());
|
|
752
724
|
}
|
|
753
725
|
}
|
|
754
|
-
|
|
726
|
+
s.expect(tokens_1.TokenType.RPAREN);
|
|
755
727
|
const body = this.parseBlock();
|
|
756
728
|
return { kind: 'fn_decl', name, params, body, source: src };
|
|
757
729
|
}
|
|
758
730
|
// --- return formula ---
|
|
759
731
|
parseReturnStmt() {
|
|
760
|
-
const
|
|
761
|
-
|
|
732
|
+
const s = this.state;
|
|
733
|
+
const src = s.loc();
|
|
734
|
+
s.expect(tokens_1.TokenType.RETURN);
|
|
762
735
|
let formula;
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
!
|
|
766
|
-
!this.checkType(tokens_1.TokenType.RBRACE)) {
|
|
736
|
+
if (!s.checkType(tokens_1.TokenType.NEWLINE) &&
|
|
737
|
+
!s.checkType(tokens_1.TokenType.EOF) &&
|
|
738
|
+
!s.checkType(tokens_1.TokenType.RBRACE)) {
|
|
767
739
|
formula = this.parseFormula();
|
|
768
740
|
}
|
|
769
741
|
return { kind: 'return_stmt', formula, source: src };
|
|
770
742
|
}
|
|
771
743
|
// --- export STATEMENT ---
|
|
772
744
|
parseExportDecl() {
|
|
773
|
-
const
|
|
774
|
-
|
|
745
|
+
const s = this.state;
|
|
746
|
+
const src = s.loc();
|
|
747
|
+
s.expect(tokens_1.TokenType.EXPORT);
|
|
775
748
|
const stmt = this.parseStatement();
|
|
776
749
|
if (!stmt) {
|
|
777
750
|
throw new Error('Se esperaba un statement después de "export"');
|
|
778
751
|
}
|
|
779
|
-
// Solo permitimos exportar declaraciones
|
|
780
752
|
const exportable = [
|
|
781
753
|
'let_decl',
|
|
782
754
|
'axiom_decl',
|
|
@@ -792,157 +764,160 @@ class Parser {
|
|
|
792
764
|
}
|
|
793
765
|
// --- define NAME(params?) := FORMULA (description "text")? ---
|
|
794
766
|
parseDefineDecl() {
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
767
|
+
const s = this.state;
|
|
768
|
+
const src = s.loc();
|
|
769
|
+
s.expect(tokens_1.TokenType.DEFINE);
|
|
770
|
+
const name = s.expectName();
|
|
799
771
|
let params;
|
|
800
|
-
if (
|
|
772
|
+
if (s.match(tokens_1.TokenType.LPAREN)) {
|
|
801
773
|
params = [];
|
|
802
|
-
if (!
|
|
803
|
-
params.push(
|
|
804
|
-
while (
|
|
805
|
-
params.push(
|
|
774
|
+
if (!s.checkType(tokens_1.TokenType.RPAREN)) {
|
|
775
|
+
params.push(s.expectName());
|
|
776
|
+
while (s.match(tokens_1.TokenType.COMMA)) {
|
|
777
|
+
params.push(s.expectName());
|
|
806
778
|
}
|
|
807
779
|
}
|
|
808
|
-
|
|
780
|
+
s.expect(tokens_1.TokenType.RPAREN);
|
|
809
781
|
}
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
this.expect(tokens_1.TokenType.EQUALS);
|
|
782
|
+
if (s.match(tokens_1.TokenType.COLON)) {
|
|
783
|
+
s.expect(tokens_1.TokenType.EQUALS);
|
|
813
784
|
}
|
|
814
785
|
else {
|
|
815
|
-
|
|
786
|
+
s.expect(tokens_1.TokenType.EQUALS);
|
|
816
787
|
}
|
|
817
788
|
const body = this.parseFormula();
|
|
818
|
-
// Optional description: description "text" (on next line or same line)
|
|
819
789
|
let description;
|
|
820
|
-
|
|
821
|
-
if (
|
|
822
|
-
|
|
823
|
-
if (
|
|
824
|
-
description =
|
|
825
|
-
|
|
790
|
+
s.skipNewlines();
|
|
791
|
+
if (s.checkType(tokens_1.TokenType.DESCRIPTION)) {
|
|
792
|
+
s.advance();
|
|
793
|
+
if (s.checkType(tokens_1.TokenType.STRING)) {
|
|
794
|
+
description = s.current().value;
|
|
795
|
+
s.advance();
|
|
826
796
|
}
|
|
827
797
|
}
|
|
828
798
|
return { kind: 'define_decl', name, params, body, description, source: src };
|
|
829
799
|
}
|
|
830
800
|
// --- unfold FORMULA ---
|
|
831
801
|
parseUnfoldCmd() {
|
|
832
|
-
const
|
|
833
|
-
|
|
802
|
+
const s = this.state;
|
|
803
|
+
const src = s.loc();
|
|
804
|
+
s.expect(tokens_1.TokenType.UNFOLD);
|
|
834
805
|
const formula = this.parseFormula();
|
|
835
806
|
return { kind: 'unfold_cmd', formula, source: src };
|
|
836
807
|
}
|
|
837
808
|
// --- fold FORMULA ---
|
|
838
809
|
parseFoldCmd() {
|
|
839
|
-
const
|
|
840
|
-
|
|
810
|
+
const s = this.state;
|
|
811
|
+
const src = s.loc();
|
|
812
|
+
s.expect(tokens_1.TokenType.FOLD);
|
|
841
813
|
const formula = this.parseFormula();
|
|
842
814
|
return { kind: 'fold_cmd', formula, source: src };
|
|
843
815
|
}
|
|
844
816
|
// --- source NAME { key "value", ... } ---
|
|
845
817
|
parseSourceDecl() {
|
|
846
|
-
const
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
818
|
+
const s = this.state;
|
|
819
|
+
const src = s.loc();
|
|
820
|
+
s.expect(tokens_1.TokenType.SOURCE_KW);
|
|
821
|
+
const name = s.expectName();
|
|
822
|
+
s.expect(tokens_1.TokenType.LBRACE);
|
|
823
|
+
s.skipNewlines();
|
|
851
824
|
const fields = [];
|
|
852
|
-
while (!
|
|
853
|
-
|
|
854
|
-
if (
|
|
825
|
+
while (!s.checkType(tokens_1.TokenType.RBRACE) && !s.isAtEnd()) {
|
|
826
|
+
s.skipNewlines();
|
|
827
|
+
if (s.checkType(tokens_1.TokenType.RBRACE))
|
|
855
828
|
break;
|
|
856
|
-
const key =
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
this.advance();
|
|
829
|
+
const key = s.expectName();
|
|
830
|
+
if (s.checkType(tokens_1.TokenType.STRING)) {
|
|
831
|
+
fields.push({ key, value: s.current().value });
|
|
832
|
+
s.advance();
|
|
861
833
|
}
|
|
862
|
-
else if (
|
|
863
|
-
fields.push({ key, value: parseFloat(
|
|
864
|
-
|
|
834
|
+
else if (s.checkType(tokens_1.TokenType.NUMBER)) {
|
|
835
|
+
fields.push({ key, value: parseFloat(s.current().value) });
|
|
836
|
+
s.advance();
|
|
865
837
|
}
|
|
866
|
-
else if (
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
this.advance();
|
|
838
|
+
else if (s.checkType(tokens_1.TokenType.MINUS)) {
|
|
839
|
+
s.advance();
|
|
840
|
+
if (s.checkType(tokens_1.TokenType.NUMBER)) {
|
|
841
|
+
fields.push({ key, value: -parseFloat(s.current().value) });
|
|
842
|
+
s.advance();
|
|
872
843
|
}
|
|
873
844
|
}
|
|
874
|
-
|
|
845
|
+
s.skipNewlines();
|
|
875
846
|
}
|
|
876
|
-
|
|
847
|
+
s.expect(tokens_1.TokenType.RBRACE);
|
|
877
848
|
return { kind: 'source_decl', name, fields, source: src };
|
|
878
849
|
}
|
|
879
850
|
// --- interpret "text" as FORMULA | interpret IDENT as FORMULA ---
|
|
880
851
|
parseInterpretCmd() {
|
|
881
|
-
const
|
|
882
|
-
|
|
852
|
+
const s = this.state;
|
|
853
|
+
const src = s.loc();
|
|
854
|
+
s.expect(tokens_1.TokenType.INTERPRET);
|
|
883
855
|
let text;
|
|
884
856
|
let passageRef;
|
|
885
|
-
if (
|
|
886
|
-
text =
|
|
887
|
-
|
|
857
|
+
if (s.checkType(tokens_1.TokenType.STRING)) {
|
|
858
|
+
text = s.current().value;
|
|
859
|
+
s.advance();
|
|
888
860
|
}
|
|
889
861
|
else {
|
|
890
|
-
|
|
891
|
-
passageRef = this.expectName();
|
|
862
|
+
passageRef = s.expectName();
|
|
892
863
|
text = passageRef;
|
|
893
864
|
}
|
|
894
|
-
|
|
865
|
+
s.expect(tokens_1.TokenType.AS);
|
|
895
866
|
const formula = this.parseFormula();
|
|
896
867
|
return { kind: 'interpret_cmd', text, passageRef, formula, source: src };
|
|
897
868
|
}
|
|
898
869
|
// --- glossary ---
|
|
899
870
|
parseGlossaryCmd() {
|
|
900
|
-
const
|
|
901
|
-
|
|
871
|
+
const s = this.state;
|
|
872
|
+
const src = s.loc();
|
|
873
|
+
s.expect(tokens_1.TokenType.GLOSSARY);
|
|
902
874
|
return { kind: 'glossary_cmd', source: src };
|
|
903
875
|
}
|
|
904
876
|
// --- nombre(arg1, arg2) — llamada a función ---
|
|
905
877
|
parseFnCall() {
|
|
906
|
-
const
|
|
907
|
-
const
|
|
908
|
-
|
|
878
|
+
const s = this.state;
|
|
879
|
+
const src = s.loc();
|
|
880
|
+
const name = s.expectName();
|
|
881
|
+
s.expect(tokens_1.TokenType.LPAREN);
|
|
909
882
|
const args = [];
|
|
910
|
-
if (!
|
|
883
|
+
if (!s.checkType(tokens_1.TokenType.RPAREN)) {
|
|
911
884
|
args.push(this.parseFormula());
|
|
912
|
-
while (
|
|
885
|
+
while (s.match(tokens_1.TokenType.COMMA)) {
|
|
913
886
|
args.push(this.parseFormula());
|
|
914
887
|
}
|
|
915
888
|
}
|
|
916
|
-
|
|
889
|
+
s.expect(tokens_1.TokenType.RPAREN);
|
|
917
890
|
return { kind: 'fn_call', name, args, source: src };
|
|
918
891
|
}
|
|
919
892
|
// --- obj.method(arg1, arg2) ---
|
|
920
893
|
parseMemberFnCall() {
|
|
921
|
-
const
|
|
922
|
-
const
|
|
923
|
-
|
|
924
|
-
|
|
894
|
+
const s = this.state;
|
|
895
|
+
const src = s.loc();
|
|
896
|
+
const obj = s.expectIdent();
|
|
897
|
+
s.expect(tokens_1.TokenType.DOT);
|
|
898
|
+
const method = s.expectIdent();
|
|
925
899
|
const fullName = `${obj}.${method}`;
|
|
926
|
-
|
|
900
|
+
s.expect(tokens_1.TokenType.LPAREN);
|
|
927
901
|
const args = [];
|
|
928
|
-
if (!
|
|
902
|
+
if (!s.checkType(tokens_1.TokenType.RPAREN)) {
|
|
929
903
|
args.push(this.parseFormula());
|
|
930
|
-
while (
|
|
904
|
+
while (s.match(tokens_1.TokenType.COMMA)) {
|
|
931
905
|
args.push(this.parseFormula());
|
|
932
906
|
}
|
|
933
907
|
}
|
|
934
|
-
|
|
908
|
+
s.expect(tokens_1.TokenType.RPAREN);
|
|
935
909
|
return { kind: 'fn_call', name: fullName, args, source: src };
|
|
936
910
|
}
|
|
937
911
|
// --- Helper: parsear un bloque { statements } ---
|
|
938
912
|
parseBlock() {
|
|
939
|
-
this.
|
|
940
|
-
|
|
941
|
-
|
|
913
|
+
const s = this.state;
|
|
914
|
+
s.skipNewlines();
|
|
915
|
+
s.expect(tokens_1.TokenType.LBRACE);
|
|
916
|
+
s.skipNewlines();
|
|
942
917
|
const body = [];
|
|
943
|
-
while (!
|
|
944
|
-
|
|
945
|
-
if (
|
|
918
|
+
while (!s.checkType(tokens_1.TokenType.RBRACE) && !s.isAtEnd()) {
|
|
919
|
+
s.skipNewlines();
|
|
920
|
+
if (s.checkType(tokens_1.TokenType.RBRACE))
|
|
946
921
|
break;
|
|
947
922
|
try {
|
|
948
923
|
const stmt = this.parseStatement();
|
|
@@ -951,611 +926,18 @@ class Parser {
|
|
|
951
926
|
}
|
|
952
927
|
catch (e) {
|
|
953
928
|
const message = e instanceof Error ? e.message : 'Error de parseo en bloque';
|
|
954
|
-
|
|
955
|
-
severity: 'error',
|
|
956
|
-
message,
|
|
957
|
-
file: this.file,
|
|
958
|
-
line: this.current().line,
|
|
959
|
-
column: this.current().column,
|
|
960
|
-
});
|
|
929
|
+
s.pushDiagnostic('error', message);
|
|
961
930
|
this.advanceToNextStatement();
|
|
962
931
|
}
|
|
963
932
|
}
|
|
964
|
-
|
|
933
|
+
s.expect(tokens_1.TokenType.RBRACE);
|
|
965
934
|
return body;
|
|
966
935
|
}
|
|
967
|
-
// ---
|
|
968
|
-
// Precedencia (de menor a mayor):
|
|
969
|
-
// 1. <-> (bicondicional)
|
|
970
|
-
// 2. -> (implicación, asocia a la derecha)
|
|
971
|
-
// 3. | (disyunción)
|
|
972
|
-
// 4. & (conjunción)
|
|
973
|
-
// 5. ! (negación) y átomos
|
|
936
|
+
// --- Delegacion a modulo de formulas ---
|
|
974
937
|
parseFormula() {
|
|
975
|
-
return this.
|
|
976
|
-
}
|
|
977
|
-
parseBiconditional() {
|
|
978
|
-
let left = this.parseImplication();
|
|
979
|
-
while (this.match(tokens_1.TokenType.BICONDITIONAL)) {
|
|
980
|
-
const right = this.parseImplication();
|
|
981
|
-
left = { kind: 'biconditional', args: [left, right], source: this.loc() };
|
|
982
|
-
}
|
|
983
|
-
return left;
|
|
984
|
-
}
|
|
985
|
-
parseImplication() {
|
|
986
|
-
const left = this.parseDisjunction();
|
|
987
|
-
if (this.match(tokens_1.TokenType.ARROW)) {
|
|
988
|
-
// Asociatividad a la derecha
|
|
989
|
-
const right = this.parseImplication();
|
|
990
|
-
return { kind: 'implies', args: [left, right], source: this.loc() };
|
|
991
|
-
}
|
|
992
|
-
return left;
|
|
993
|
-
}
|
|
994
|
-
parseDisjunction() {
|
|
995
|
-
let left = this.parseUntil();
|
|
996
|
-
let firstKind = null;
|
|
997
|
-
while (this.match(tokens_1.TokenType.OR) || this.match(tokens_1.TokenType.XOR) || this.match(tokens_1.TokenType.NOR)) {
|
|
998
|
-
const type = this.previous().type;
|
|
999
|
-
const currentKind = type === tokens_1.TokenType.OR ? 'or' : type === tokens_1.TokenType.XOR ? 'xor' : 'nor';
|
|
1000
|
-
if (firstKind !== null && firstKind !== currentKind) {
|
|
1001
|
-
const tok = this.previous();
|
|
1002
|
-
this.diagnostics.push({
|
|
1003
|
-
severity: 'warning',
|
|
1004
|
-
message: `Mezcla de conectivos ${firstKind}/${currentKind} al mismo nivel de precedencia; asociación izquierda aplicada — usar paréntesis para desambiguar`,
|
|
1005
|
-
file: this.file,
|
|
1006
|
-
line: tok.line,
|
|
1007
|
-
column: tok.column,
|
|
1008
|
-
});
|
|
1009
|
-
}
|
|
1010
|
-
firstKind = firstKind ?? currentKind;
|
|
1011
|
-
const right = this.parseUntil();
|
|
1012
|
-
left = { kind: currentKind, args: [left, right], source: this.loc() };
|
|
1013
|
-
}
|
|
1014
|
-
return left;
|
|
1015
|
-
}
|
|
1016
|
-
parseUntil() {
|
|
1017
|
-
let left = this.parseConjunction();
|
|
1018
|
-
while (this.match(tokens_1.TokenType.UNTIL)) {
|
|
1019
|
-
const right = this.parseConjunction();
|
|
1020
|
-
left = { kind: 'temporal_until', args: [left, right], source: this.loc() };
|
|
1021
|
-
}
|
|
1022
|
-
return left;
|
|
1023
|
-
}
|
|
1024
|
-
parseConjunction() {
|
|
1025
|
-
let left = this.parseComparison();
|
|
1026
|
-
let firstKind = null;
|
|
1027
|
-
while (this.match(tokens_1.TokenType.AND) || this.match(tokens_1.TokenType.NAND)) {
|
|
1028
|
-
const type = this.previous().type;
|
|
1029
|
-
const currentKind = type === tokens_1.TokenType.AND ? 'and' : 'nand';
|
|
1030
|
-
if (firstKind !== null && firstKind !== currentKind) {
|
|
1031
|
-
const tok = this.previous();
|
|
1032
|
-
this.diagnostics.push({
|
|
1033
|
-
severity: 'warning',
|
|
1034
|
-
message: `Mezcla de conectivos ${firstKind}/${currentKind} al mismo nivel de precedencia; asociación izquierda aplicada — usar paréntesis para desambiguar`,
|
|
1035
|
-
file: this.file,
|
|
1036
|
-
line: tok.line,
|
|
1037
|
-
column: tok.column,
|
|
1038
|
-
});
|
|
1039
|
-
}
|
|
1040
|
-
firstKind = firstKind ?? currentKind;
|
|
1041
|
-
const right = this.parseComparison();
|
|
1042
|
-
left = { kind: currentKind, args: [left, right], source: this.loc() };
|
|
1043
|
-
}
|
|
1044
|
-
return left;
|
|
1045
|
-
}
|
|
1046
|
-
// --- Arithmetic precedence ---
|
|
1047
|
-
parseComparison() {
|
|
1048
|
-
let left = this.parseAdditive();
|
|
1049
|
-
while (this.checkType(tokens_1.TokenType.LT) ||
|
|
1050
|
-
this.checkType(tokens_1.TokenType.GT) ||
|
|
1051
|
-
this.checkType(tokens_1.TokenType.LTE) ||
|
|
1052
|
-
this.checkType(tokens_1.TokenType.GTE)) {
|
|
1053
|
-
if (this.match(tokens_1.TokenType.LT)) {
|
|
1054
|
-
const right = this.parseAdditive();
|
|
1055
|
-
left = { kind: 'less', args: [left, right], source: this.loc() };
|
|
1056
|
-
}
|
|
1057
|
-
else if (this.match(tokens_1.TokenType.GT)) {
|
|
1058
|
-
const right = this.parseAdditive();
|
|
1059
|
-
left = { kind: 'greater', args: [left, right], source: this.loc() };
|
|
1060
|
-
}
|
|
1061
|
-
else if (this.match(tokens_1.TokenType.LTE)) {
|
|
1062
|
-
const right = this.parseAdditive();
|
|
1063
|
-
left = { kind: 'less_eq', args: [left, right], source: this.loc() };
|
|
1064
|
-
}
|
|
1065
|
-
else if (this.match(tokens_1.TokenType.GTE)) {
|
|
1066
|
-
const right = this.parseAdditive();
|
|
1067
|
-
left = { kind: 'greater_eq', args: [left, right], source: this.loc() };
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
return left;
|
|
1071
|
-
}
|
|
1072
|
-
parseAdditive() {
|
|
1073
|
-
let left = this.parseMultiplicative();
|
|
1074
|
-
while (this.checkType(tokens_1.TokenType.PLUS) || this.checkType(tokens_1.TokenType.MINUS)) {
|
|
1075
|
-
if (this.match(tokens_1.TokenType.PLUS)) {
|
|
1076
|
-
const right = this.parseMultiplicative();
|
|
1077
|
-
left = { kind: 'add', args: [left, right], source: this.loc() };
|
|
1078
|
-
}
|
|
1079
|
-
else if (this.match(tokens_1.TokenType.MINUS)) {
|
|
1080
|
-
const right = this.parseMultiplicative();
|
|
1081
|
-
left = { kind: 'subtract', args: [left, right], source: this.loc() };
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
return left;
|
|
1085
|
-
}
|
|
1086
|
-
parseMultiplicative() {
|
|
1087
|
-
let left = this.parseUnary();
|
|
1088
|
-
while (this.checkType(tokens_1.TokenType.STAR) ||
|
|
1089
|
-
this.checkType(tokens_1.TokenType.SLASH) ||
|
|
1090
|
-
this.checkType(tokens_1.TokenType.PERCENT)) {
|
|
1091
|
-
if (this.match(tokens_1.TokenType.STAR)) {
|
|
1092
|
-
const right = this.parseUnary();
|
|
1093
|
-
left = { kind: 'multiply', args: [left, right], source: this.loc() };
|
|
1094
|
-
}
|
|
1095
|
-
else if (this.match(tokens_1.TokenType.SLASH)) {
|
|
1096
|
-
const right = this.parseUnary();
|
|
1097
|
-
left = { kind: 'divide', args: [left, right], source: this.loc() };
|
|
1098
|
-
}
|
|
1099
|
-
else if (this.match(tokens_1.TokenType.PERCENT)) {
|
|
1100
|
-
const right = this.parseUnary();
|
|
1101
|
-
left = { kind: 'modulo', args: [left, right], source: this.loc() };
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
return left;
|
|
1105
|
-
}
|
|
1106
|
-
parseUnary() {
|
|
1107
|
-
// Unary minus: -expr → subtract(0, expr)
|
|
1108
|
-
if (this.match(tokens_1.TokenType.MINUS)) {
|
|
1109
|
-
const operand = this.parseUnary();
|
|
1110
|
-
return {
|
|
1111
|
-
kind: 'subtract',
|
|
1112
|
-
args: [{ kind: 'number', value: 0, source: this.loc() }, operand],
|
|
1113
|
-
source: this.loc(),
|
|
1114
|
-
};
|
|
1115
|
-
}
|
|
1116
|
-
if (this.match(tokens_1.TokenType.NOT)) {
|
|
1117
|
-
const operand = this.parseUnary();
|
|
1118
|
-
return { kind: 'not', args: [operand], source: this.loc() };
|
|
1119
|
-
}
|
|
1120
|
-
if (this.match(tokens_1.TokenType.BOX)) {
|
|
1121
|
-
const operand = this.parseUnary();
|
|
1122
|
-
return { kind: 'modal_necessity', args: [operand], source: this.loc() };
|
|
1123
|
-
}
|
|
1124
|
-
if (this.match(tokens_1.TokenType.DIAMOND)) {
|
|
1125
|
-
const operand = this.parseUnary();
|
|
1126
|
-
return { kind: 'modal_possibility', args: [operand], source: this.loc() };
|
|
1127
|
-
}
|
|
1128
|
-
if (this.match(tokens_1.TokenType.FORALL)) {
|
|
1129
|
-
const variable = this.expectIdent();
|
|
1130
|
-
const operand = this.parseUnary();
|
|
1131
|
-
return { kind: 'forall', variable, args: [operand], source: this.loc() };
|
|
1132
|
-
}
|
|
1133
|
-
if (this.match(tokens_1.TokenType.EXISTS)) {
|
|
1134
|
-
const variable = this.expectIdent();
|
|
1135
|
-
const operand = this.parseUnary();
|
|
1136
|
-
return { kind: 'exists', variable, args: [operand], source: this.loc() };
|
|
1137
|
-
}
|
|
1138
|
-
if (this.match(tokens_1.TokenType.NEXT)) {
|
|
1139
|
-
const operand = this.parseUnary();
|
|
1140
|
-
return { kind: 'temporal_next', args: [operand], source: this.loc() };
|
|
1141
|
-
}
|
|
1142
|
-
return this.parsePostfix();
|
|
1143
|
-
}
|
|
1144
|
-
parsePostfix() {
|
|
1145
|
-
let expr = this.parsePrimary();
|
|
1146
|
-
while (this.match(tokens_1.TokenType.LBRACKET)) {
|
|
1147
|
-
const index = this.parseFormula();
|
|
1148
|
-
this.expect(tokens_1.TokenType.RBRACKET);
|
|
1149
|
-
expr = {
|
|
1150
|
-
kind: 'fn_call',
|
|
1151
|
-
name: 'at',
|
|
1152
|
-
args: [expr, index],
|
|
1153
|
-
source: expr.source ?? index.source ?? this.loc(),
|
|
1154
|
-
};
|
|
1155
|
-
}
|
|
1156
|
-
return expr;
|
|
1157
|
-
}
|
|
1158
|
-
parsePrimary() {
|
|
1159
|
-
// Constantes lógicas ⊤/⊥ (true/false/verdadero/falso)
|
|
1160
|
-
if (this.checkType(tokens_1.TokenType.TRUE_CONST)) {
|
|
1161
|
-
const tok = this.current();
|
|
1162
|
-
this.advance();
|
|
1163
|
-
return { kind: 'true', source: { line: tok.line, column: tok.column } };
|
|
1164
|
-
}
|
|
1165
|
-
if (this.checkType(tokens_1.TokenType.FALSE_CONST)) {
|
|
1166
|
-
const tok = this.current();
|
|
1167
|
-
this.advance();
|
|
1168
|
-
return { kind: 'false', source: { line: tok.line, column: tok.column } };
|
|
1169
|
-
}
|
|
1170
|
-
// Literal numérico
|
|
1171
|
-
if (this.checkType(tokens_1.TokenType.NUMBER)) {
|
|
1172
|
-
const tok = this.current();
|
|
1173
|
-
this.advance();
|
|
1174
|
-
return {
|
|
1175
|
-
kind: 'number',
|
|
1176
|
-
value: parseFloat(tok.value),
|
|
1177
|
-
source: { line: tok.line, column: tok.column },
|
|
1178
|
-
};
|
|
1179
|
-
}
|
|
1180
|
-
if (this.match(tokens_1.TokenType.LBRACKET)) {
|
|
1181
|
-
const items = [];
|
|
1182
|
-
if (!this.checkType(tokens_1.TokenType.RBRACKET)) {
|
|
1183
|
-
items.push(this.parseFormula());
|
|
1184
|
-
while (this.match(tokens_1.TokenType.COMMA)) {
|
|
1185
|
-
items.push(this.parseFormula());
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
1188
|
-
this.expect(tokens_1.TokenType.RBRACKET);
|
|
1189
|
-
return {
|
|
1190
|
-
kind: 'list',
|
|
1191
|
-
args: items,
|
|
1192
|
-
source: this.loc(),
|
|
1193
|
-
};
|
|
1194
|
-
}
|
|
1195
|
-
// Literal de texto (String)
|
|
1196
|
-
if (this.checkType(tokens_1.TokenType.STRING)) {
|
|
1197
|
-
const tok = this.current();
|
|
1198
|
-
this.advance();
|
|
1199
|
-
// Lo representamos como un átomo especial o un nuevo kind.
|
|
1200
|
-
// Por simplicidad para el motor lógico, lo tratamos como un átomo cuyo nombre es el valor del string entre comillas.
|
|
1201
|
-
return {
|
|
1202
|
-
kind: 'atom',
|
|
1203
|
-
name: `"${tok.value}"`,
|
|
1204
|
-
source: { line: tok.line, column: tok.column },
|
|
1205
|
-
};
|
|
1206
|
-
}
|
|
1207
|
-
// Paréntesis
|
|
1208
|
-
if (this.match(tokens_1.TokenType.LPAREN)) {
|
|
1209
|
-
const inner = this.parseFormula();
|
|
1210
|
-
this.expect(tokens_1.TokenType.RPAREN);
|
|
1211
|
-
return inner;
|
|
1212
|
-
}
|
|
1213
|
-
// Dot notation con keyword como prefijo: Logic.mp, Theory.axiom, etc.
|
|
1214
|
-
// Si el token actual es una keyword seguida de DOT + IDENTIFIER, tratarlo como nombre calificado
|
|
1215
|
-
if (this.checkType(tokens_1.TokenType.DOT) === false &&
|
|
1216
|
-
this.current().type !== tokens_1.TokenType.IDENTIFIER &&
|
|
1217
|
-
this.current().type !== tokens_1.TokenType.NEWLINE &&
|
|
1218
|
-
this.current().type !== tokens_1.TokenType.EOF &&
|
|
1219
|
-
this.peek(1) === tokens_1.TokenType.DOT &&
|
|
1220
|
-
this.peek(2) === tokens_1.TokenType.IDENTIFIER) {
|
|
1221
|
-
const tok = this.current();
|
|
1222
|
-
this.advance(); // consumir keyword
|
|
1223
|
-
this.advance(); // consumir DOT
|
|
1224
|
-
const memberTok = this.current();
|
|
1225
|
-
this.advance(); // consumir IDENTIFIER
|
|
1226
|
-
return {
|
|
1227
|
-
kind: 'atom',
|
|
1228
|
-
name: `${tok.value}.${memberTok.value}`,
|
|
1229
|
-
source: { line: tok.line, column: tok.column },
|
|
1230
|
-
};
|
|
1231
|
-
}
|
|
1232
|
-
// Predicado o Atomo proposicional
|
|
1233
|
-
if (this.checkType(tokens_1.TokenType.IDENTIFIER)) {
|
|
1234
|
-
const tok = this.current();
|
|
1235
|
-
this.advance();
|
|
1236
|
-
// Notación con punto: Theory.member (acceso calificado)
|
|
1237
|
-
if (this.checkType(tokens_1.TokenType.DOT) && this.peek(1) === tokens_1.TokenType.IDENTIFIER) {
|
|
1238
|
-
this.advance(); // consumir DOT
|
|
1239
|
-
const memberTok = this.current();
|
|
1240
|
-
this.advance(); // consumir IDENTIFIER
|
|
1241
|
-
// Nombre calificado: "Theory.member"
|
|
1242
|
-
return {
|
|
1243
|
-
kind: 'atom',
|
|
1244
|
-
name: `${tok.value}.${memberTok.value}`,
|
|
1245
|
-
source: { line: tok.line, column: tok.column },
|
|
1246
|
-
};
|
|
1247
|
-
}
|
|
1248
|
-
if (this.match(tokens_1.TokenType.LPAREN)) {
|
|
1249
|
-
// Modal alias check: e.g. K(P) in epistemic, O(P) in deontic
|
|
1250
|
-
const profileAliases = MODAL_ALIASES[this.currentProfile];
|
|
1251
|
-
const aliasType = profileAliases?.[tok.value];
|
|
1252
|
-
if (aliasType) {
|
|
1253
|
-
const inner = this.parseFormula();
|
|
1254
|
-
this.expect(tokens_1.TokenType.RPAREN);
|
|
1255
|
-
if (aliasType === 'box') {
|
|
1256
|
-
return {
|
|
1257
|
-
kind: 'modal_necessity',
|
|
1258
|
-
args: [inner],
|
|
1259
|
-
source: { line: tok.line, column: tok.column },
|
|
1260
|
-
};
|
|
1261
|
-
}
|
|
1262
|
-
else if (aliasType === 'diamond') {
|
|
1263
|
-
return {
|
|
1264
|
-
kind: 'modal_possibility',
|
|
1265
|
-
args: [inner],
|
|
1266
|
-
source: { line: tok.line, column: tok.column },
|
|
1267
|
-
};
|
|
1268
|
-
}
|
|
1269
|
-
else {
|
|
1270
|
-
// box_not: e.g. deontic F(φ) = □(¬φ)
|
|
1271
|
-
return {
|
|
1272
|
-
kind: 'modal_necessity',
|
|
1273
|
-
args: [
|
|
1274
|
-
{ kind: 'not', args: [inner], source: { line: tok.line, column: tok.column } },
|
|
1275
|
-
],
|
|
1276
|
-
source: { line: tok.line, column: tok.column },
|
|
1277
|
-
};
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1280
|
-
// Podría ser un predicado P(x, y) o una llamada a función fn(arg1, arg2)
|
|
1281
|
-
if (this.knownFunctionNames.has(tok.value) || this.knownTheoryNames.has(tok.value)) {
|
|
1282
|
-
const args = [];
|
|
1283
|
-
if (!this.checkType(tokens_1.TokenType.RPAREN)) {
|
|
1284
|
-
args.push(this.parseFormula());
|
|
1285
|
-
while (this.match(tokens_1.TokenType.COMMA)) {
|
|
1286
|
-
args.push(this.parseFormula());
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
this.expect(tokens_1.TokenType.RPAREN);
|
|
1290
|
-
return {
|
|
1291
|
-
kind: 'fn_call',
|
|
1292
|
-
name: tok.value,
|
|
1293
|
-
args,
|
|
1294
|
-
source: { line: tok.line, column: tok.column },
|
|
1295
|
-
};
|
|
1296
|
-
}
|
|
1297
|
-
// Predicado: P(x, y, ...)
|
|
1298
|
-
const args = [];
|
|
1299
|
-
if (!this.checkType(tokens_1.TokenType.RPAREN)) {
|
|
1300
|
-
args.push(this.parseFormula());
|
|
1301
|
-
while (this.match(tokens_1.TokenType.COMMA)) {
|
|
1302
|
-
args.push(this.parseFormula());
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
|
-
this.expect(tokens_1.TokenType.RPAREN);
|
|
1306
|
-
const paramStrings = args.map((a) => this.formulaToString(a));
|
|
1307
|
-
const predFormula = {
|
|
1308
|
-
kind: 'predicate',
|
|
1309
|
-
name: tok.value,
|
|
1310
|
-
params: paramStrings,
|
|
1311
|
-
source: { line: tok.line, column: tok.column },
|
|
1312
|
-
};
|
|
1313
|
-
// FOL igualdad: P(x) = Q(y) (raro pero posible)
|
|
1314
|
-
if (this.checkType(tokens_1.TokenType.EQUALS)) {
|
|
1315
|
-
this.advance();
|
|
1316
|
-
const right = this.parsePrimary();
|
|
1317
|
-
return {
|
|
1318
|
-
kind: 'equals',
|
|
1319
|
-
args: [predFormula, right],
|
|
1320
|
-
source: { line: tok.line, column: tok.column },
|
|
1321
|
-
};
|
|
1322
|
-
}
|
|
1323
|
-
return predFormula;
|
|
1324
|
-
}
|
|
1325
|
-
// FOL igualdad: x = y (identidad entre términos)
|
|
1326
|
-
if (this.checkType(tokens_1.TokenType.EQUALS)) {
|
|
1327
|
-
this.advance();
|
|
1328
|
-
const rightTok = this.current();
|
|
1329
|
-
if (this.checkType(tokens_1.TokenType.IDENTIFIER)) {
|
|
1330
|
-
this.advance();
|
|
1331
|
-
const left = {
|
|
1332
|
-
kind: 'atom',
|
|
1333
|
-
name: tok.value,
|
|
1334
|
-
source: { line: tok.line, column: tok.column },
|
|
1335
|
-
};
|
|
1336
|
-
const right = {
|
|
1337
|
-
kind: 'atom',
|
|
1338
|
-
name: rightTok.value,
|
|
1339
|
-
source: { line: rightTok.line, column: rightTok.column },
|
|
1340
|
-
};
|
|
1341
|
-
return {
|
|
1342
|
-
kind: 'equals',
|
|
1343
|
-
args: [left, right],
|
|
1344
|
-
source: { line: tok.line, column: tok.column },
|
|
1345
|
-
};
|
|
1346
|
-
}
|
|
1347
|
-
// Si no es un identificador, backtrack — el = pertenece al statement
|
|
1348
|
-
this.pos--;
|
|
1349
|
-
}
|
|
1350
|
-
return { kind: 'atom', name: tok.value, source: { line: tok.line, column: tok.column } };
|
|
1351
|
-
}
|
|
1352
|
-
throw new Error(`Se esperaba formula en linea ${this.current().line}, columna ${this.current().column}, ` +
|
|
1353
|
-
`encontrado: '${this.current().value}' (${this.current().type})`);
|
|
1354
|
-
}
|
|
1355
|
-
// --- Helpers ---
|
|
1356
|
-
parseIdList() {
|
|
1357
|
-
this.expect(tokens_1.TokenType.LBRACE);
|
|
1358
|
-
const ids = [];
|
|
1359
|
-
if (!this.checkType(tokens_1.TokenType.RBRACE)) {
|
|
1360
|
-
ids.push(this.expectIdent());
|
|
1361
|
-
while (this.match(tokens_1.TokenType.COMMA)) {
|
|
1362
|
-
ids.push(this.expectIdent());
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1365
|
-
this.expect(tokens_1.TokenType.RBRACE);
|
|
1366
|
-
return ids;
|
|
1367
|
-
}
|
|
1368
|
-
collectAssociativeArgs(f, kind) {
|
|
1369
|
-
if (f.kind !== kind || !f.args?.length)
|
|
1370
|
-
return [f];
|
|
1371
|
-
const items = [];
|
|
1372
|
-
for (const arg of f.args) {
|
|
1373
|
-
if (!arg)
|
|
1374
|
-
continue;
|
|
1375
|
-
items.push(...this.collectAssociativeArgs(arg, kind));
|
|
1376
|
-
}
|
|
1377
|
-
return items;
|
|
1378
|
-
}
|
|
1379
|
-
formulaToString(f) {
|
|
1380
|
-
const arg0 = f.args?.[0];
|
|
1381
|
-
const arg1 = f.args?.[1];
|
|
1382
|
-
switch (f.kind) {
|
|
1383
|
-
case 'atom':
|
|
1384
|
-
return f.name || '?';
|
|
1385
|
-
case 'list':
|
|
1386
|
-
return `[${(f.args ?? []).map((a) => this.formulaToString(a)).join(', ')}]`;
|
|
1387
|
-
case 'number':
|
|
1388
|
-
return f.value !== undefined ? String(f.value) : '?';
|
|
1389
|
-
case 'not':
|
|
1390
|
-
return arg0 ? `!${this.formulaToString(arg0)}` : '!?';
|
|
1391
|
-
case 'modal_necessity':
|
|
1392
|
-
return arg0 ? `[]${this.formulaToString(arg0)}` : '[]?';
|
|
1393
|
-
case 'modal_possibility':
|
|
1394
|
-
return arg0 ? `<>${this.formulaToString(arg0)}` : '<>?';
|
|
1395
|
-
case 'forall':
|
|
1396
|
-
return arg0
|
|
1397
|
-
? `forall ${f.variable} ${this.formulaToString(arg0)}`
|
|
1398
|
-
: `forall ${f.variable} ?`;
|
|
1399
|
-
case 'exists':
|
|
1400
|
-
return arg0
|
|
1401
|
-
? `exists ${f.variable} ${this.formulaToString(arg0)}`
|
|
1402
|
-
: `exists ${f.variable} ?`;
|
|
1403
|
-
case 'predicate': {
|
|
1404
|
-
const params = f.params || [];
|
|
1405
|
-
return `${f.name || '?'}(${params.join(', ')})`;
|
|
1406
|
-
}
|
|
1407
|
-
case 'and':
|
|
1408
|
-
return arg0 && arg1
|
|
1409
|
-
? `(${this.collectAssociativeArgs(f, 'and')
|
|
1410
|
-
.map((a) => this.formulaToString(a))
|
|
1411
|
-
.join(' & ')})`
|
|
1412
|
-
: '(? & ?)';
|
|
1413
|
-
case 'or':
|
|
1414
|
-
return arg0 && arg1
|
|
1415
|
-
? `(${this.collectAssociativeArgs(f, 'or')
|
|
1416
|
-
.map((a) => this.formulaToString(a))
|
|
1417
|
-
.join(' | ')})`
|
|
1418
|
-
: '(? | ?)';
|
|
1419
|
-
case 'nand':
|
|
1420
|
-
return arg0 && arg1
|
|
1421
|
-
? `(${this.formulaToString(arg0)} ↑ ${this.formulaToString(arg1)})`
|
|
1422
|
-
: '(? ↑ ?)';
|
|
1423
|
-
case 'nor':
|
|
1424
|
-
return arg0 && arg1
|
|
1425
|
-
? `(${this.formulaToString(arg0)} ↓ ${this.formulaToString(arg1)})`
|
|
1426
|
-
: '(? ↓ ?)';
|
|
1427
|
-
case 'xor':
|
|
1428
|
-
return arg0 && arg1
|
|
1429
|
-
? `(${this.collectAssociativeArgs(f, 'xor')
|
|
1430
|
-
.map((a) => this.formulaToString(a))
|
|
1431
|
-
.join(' ⊕ ')})`
|
|
1432
|
-
: '(? ⊕ ?)';
|
|
1433
|
-
case 'implies':
|
|
1434
|
-
return arg0 && arg1
|
|
1435
|
-
? `(${this.formulaToString(arg0)} -> ${this.formulaToString(arg1)})`
|
|
1436
|
-
: '(? -> ?)';
|
|
1437
|
-
case 'biconditional':
|
|
1438
|
-
return arg0 && arg1
|
|
1439
|
-
? `(${this.formulaToString(arg0)} <-> ${this.formulaToString(arg1)})`
|
|
1440
|
-
: '(? <-> ?)';
|
|
1441
|
-
case 'equals':
|
|
1442
|
-
return arg0 && arg1
|
|
1443
|
-
? `(${this.formulaToString(arg0)} = ${this.formulaToString(arg1)})`
|
|
1444
|
-
: '(? = ?)';
|
|
1445
|
-
case 'temporal_next':
|
|
1446
|
-
return arg0 ? `X(${this.formulaToString(arg0)})` : 'X(?)';
|
|
1447
|
-
case 'temporal_until':
|
|
1448
|
-
return arg0 && arg1
|
|
1449
|
-
? `(${this.formulaToString(arg0)} U ${this.formulaToString(arg1)})`
|
|
1450
|
-
: '(? U ?)';
|
|
1451
|
-
case 'fn_call':
|
|
1452
|
-
return `${f.name || '?'}(${(f.args ?? []).map((a) => this.formulaToString(a)).join(', ')})`;
|
|
1453
|
-
default:
|
|
1454
|
-
return '?';
|
|
1455
|
-
}
|
|
1456
|
-
}
|
|
1457
|
-
current() {
|
|
1458
|
-
if (this.pos >= this.tokens.length) {
|
|
1459
|
-
return { type: tokens_1.TokenType.EOF, value: '', line: 0, column: 0 };
|
|
1460
|
-
}
|
|
1461
|
-
return this.tokens[this.pos];
|
|
1462
|
-
}
|
|
1463
|
-
previous() {
|
|
1464
|
-
if (this.pos === 0)
|
|
1465
|
-
return this.tokens[0];
|
|
1466
|
-
return this.tokens[this.pos - 1];
|
|
1467
|
-
}
|
|
1468
|
-
peek(offset) {
|
|
1469
|
-
const idx = this.pos + offset;
|
|
1470
|
-
if (idx >= this.tokens.length)
|
|
1471
|
-
return tokens_1.TokenType.EOF;
|
|
1472
|
-
return this.tokens[idx].type;
|
|
1473
|
-
}
|
|
1474
|
-
advance() {
|
|
1475
|
-
const tok = this.current();
|
|
1476
|
-
this.pos++;
|
|
1477
|
-
return tok;
|
|
1478
|
-
}
|
|
1479
|
-
isAtEnd() {
|
|
1480
|
-
return this.current().type === tokens_1.TokenType.EOF;
|
|
1481
|
-
}
|
|
1482
|
-
checkType(type) {
|
|
1483
|
-
return this.current().type === type;
|
|
1484
|
-
}
|
|
1485
|
-
match(type) {
|
|
1486
|
-
if (this.checkType(type)) {
|
|
1487
|
-
this.advance();
|
|
1488
|
-
return true;
|
|
1489
|
-
}
|
|
1490
|
-
return false;
|
|
1491
|
-
}
|
|
1492
|
-
expect(type) {
|
|
1493
|
-
if (this.checkType(type)) {
|
|
1494
|
-
return this.advance();
|
|
1495
|
-
}
|
|
1496
|
-
throw new Error(this.contextualize(`Se esperaba ${type}, encontrado '${this.current().value}' (${this.current().type}) ` +
|
|
1497
|
-
`en linea ${this.current().line}, columna ${this.current().column}`));
|
|
1498
|
-
}
|
|
1499
|
-
expectOneOf(...types) {
|
|
1500
|
-
for (const type of types) {
|
|
1501
|
-
if (this.checkType(type)) {
|
|
1502
|
-
return this.advance();
|
|
1503
|
-
}
|
|
1504
|
-
}
|
|
1505
|
-
throw new Error(this.contextualize(`Se esperaba ${types.join(' o ')}, encontrado '${this.current().value}' (${this.current().type}) ` +
|
|
1506
|
-
`en linea ${this.current().line}, columna ${this.current().column}`));
|
|
1507
|
-
}
|
|
1508
|
-
expectIdent() {
|
|
1509
|
-
const tok = this.expect(tokens_1.TokenType.IDENTIFIER);
|
|
1510
|
-
return tok.value;
|
|
1511
|
-
}
|
|
1512
|
-
/**
|
|
1513
|
-
* Acepta un IDENTIFIER o cualquier keyword como nombre
|
|
1514
|
-
* (para soportar nombres como "Logic", "Theory", etc. que colisionan con keywords)
|
|
1515
|
-
*/
|
|
1516
|
-
expectName() {
|
|
1517
|
-
const tok = this.current();
|
|
1518
|
-
if (tok.type === tokens_1.TokenType.IDENTIFIER) {
|
|
1519
|
-
this.advance();
|
|
1520
|
-
return tok.value;
|
|
1521
|
-
}
|
|
1522
|
-
// Aceptar cualquier keyword como nombre en contextos de nombre
|
|
1523
|
-
if (tok.type !== tokens_1.TokenType.NEWLINE &&
|
|
1524
|
-
tok.type !== tokens_1.TokenType.EOF &&
|
|
1525
|
-
tok.type !== tokens_1.TokenType.LPAREN &&
|
|
1526
|
-
tok.type !== tokens_1.TokenType.RPAREN &&
|
|
1527
|
-
tok.type !== tokens_1.TokenType.LBRACE &&
|
|
1528
|
-
tok.type !== tokens_1.TokenType.RBRACE &&
|
|
1529
|
-
tok.type !== tokens_1.TokenType.COLON &&
|
|
1530
|
-
tok.type !== tokens_1.TokenType.EQUALS &&
|
|
1531
|
-
tok.type !== tokens_1.TokenType.ARROW &&
|
|
1532
|
-
tok.type !== tokens_1.TokenType.AND &&
|
|
1533
|
-
tok.type !== tokens_1.TokenType.OR &&
|
|
1534
|
-
tok.type !== tokens_1.TokenType.NOT &&
|
|
1535
|
-
tok.type !== tokens_1.TokenType.DOT &&
|
|
1536
|
-
tok.type !== tokens_1.TokenType.COMMA &&
|
|
1537
|
-
tok.type !== tokens_1.TokenType.STRING &&
|
|
1538
|
-
tok.type !== tokens_1.TokenType.NUMBER) {
|
|
1539
|
-
this.advance();
|
|
1540
|
-
return tok.value;
|
|
1541
|
-
}
|
|
1542
|
-
throw new Error(this.contextualize(`Se esperaba nombre/identificador, encontrado '${tok.value}' (${tok.type}) ` +
|
|
1543
|
-
`en linea ${tok.line}, columna ${tok.column}`));
|
|
1544
|
-
}
|
|
1545
|
-
contextualize(message) {
|
|
1546
|
-
if (this.contextStack.length === 0)
|
|
1547
|
-
return message;
|
|
1548
|
-
return `${message} mientras se parseaba ${this.contextStack.join(' > ')}`;
|
|
1549
|
-
}
|
|
1550
|
-
withContext(context, fn) {
|
|
1551
|
-
this.contextStack.push(context);
|
|
1552
|
-
try {
|
|
1553
|
-
return fn();
|
|
1554
|
-
}
|
|
1555
|
-
finally {
|
|
1556
|
-
this.contextStack.pop();
|
|
1557
|
-
}
|
|
938
|
+
return (0, formulas_1.parseFormula)(this.state);
|
|
1558
939
|
}
|
|
940
|
+
// --- Helpers de diagnostico/descripcion ---
|
|
1559
941
|
describeStatementContext(tok) {
|
|
1560
942
|
switch (tok.type) {
|
|
1561
943
|
case tokens_1.TokenType.LOGIC:
|
|
@@ -1629,17 +1011,8 @@ class Parser {
|
|
|
1629
1011
|
return `statement '${tok.value}'`;
|
|
1630
1012
|
}
|
|
1631
1013
|
}
|
|
1632
|
-
loc() {
|
|
1633
|
-
const tok = this.current();
|
|
1634
|
-
return { line: tok.line, column: tok.column, file: this.file };
|
|
1635
|
-
}
|
|
1636
|
-
skipNewlines() {
|
|
1637
|
-
while (this.checkType(tokens_1.TokenType.NEWLINE)) {
|
|
1638
|
-
this.advance();
|
|
1639
|
-
}
|
|
1640
|
-
}
|
|
1641
1014
|
advanceToNextStatement() {
|
|
1642
|
-
|
|
1015
|
+
const s = this.state;
|
|
1643
1016
|
const statementStarters = new Set([
|
|
1644
1017
|
tokens_1.TokenType.LOGIC,
|
|
1645
1018
|
tokens_1.TokenType.AXIOM,
|
|
@@ -1682,35 +1055,35 @@ class Parser {
|
|
|
1682
1055
|
let parenDepth = 0;
|
|
1683
1056
|
let braceDepth = 0;
|
|
1684
1057
|
let bracketDepth = 0;
|
|
1685
|
-
while (!
|
|
1686
|
-
if (
|
|
1058
|
+
while (!s.isAtEnd()) {
|
|
1059
|
+
if (s.checkType(tokens_1.TokenType.NEWLINE) &&
|
|
1687
1060
|
parenDepth === 0 &&
|
|
1688
1061
|
braceDepth === 0 &&
|
|
1689
1062
|
bracketDepth === 0) {
|
|
1690
|
-
|
|
1063
|
+
s.skipNewlines();
|
|
1691
1064
|
return;
|
|
1692
1065
|
}
|
|
1693
1066
|
if (parenDepth === 0 &&
|
|
1694
1067
|
braceDepth === 0 &&
|
|
1695
1068
|
bracketDepth === 0 &&
|
|
1696
|
-
statementStarters.has(
|
|
1697
|
-
return;
|
|
1069
|
+
statementStarters.has(s.current().type)) {
|
|
1070
|
+
return;
|
|
1698
1071
|
}
|
|
1699
|
-
if (
|
|
1072
|
+
if (s.checkType(tokens_1.TokenType.LPAREN))
|
|
1700
1073
|
parenDepth += 1;
|
|
1701
|
-
else if (
|
|
1074
|
+
else if (s.checkType(tokens_1.TokenType.RPAREN))
|
|
1702
1075
|
parenDepth = Math.max(0, parenDepth - 1);
|
|
1703
|
-
else if (
|
|
1076
|
+
else if (s.checkType(tokens_1.TokenType.LBRACE))
|
|
1704
1077
|
braceDepth += 1;
|
|
1705
|
-
else if (
|
|
1078
|
+
else if (s.checkType(tokens_1.TokenType.RBRACE))
|
|
1706
1079
|
braceDepth = Math.max(0, braceDepth - 1);
|
|
1707
|
-
else if (
|
|
1080
|
+
else if (s.checkType(tokens_1.TokenType.LBRACKET) || s.checkType(tokens_1.TokenType.LBRACKET_DOUBLE)) {
|
|
1708
1081
|
bracketDepth += 1;
|
|
1709
1082
|
}
|
|
1710
|
-
else if (
|
|
1083
|
+
else if (s.checkType(tokens_1.TokenType.RBRACKET) || s.checkType(tokens_1.TokenType.RBRACKET_DOUBLE)) {
|
|
1711
1084
|
bracketDepth = Math.max(0, bracketDepth - 1);
|
|
1712
1085
|
}
|
|
1713
|
-
|
|
1086
|
+
s.advance();
|
|
1714
1087
|
}
|
|
1715
1088
|
}
|
|
1716
1089
|
}
|