dv-flow-mgr 0.0.1.13335470340a1__tar.gz → 0.0.1.13468776985a1__tar.gz

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.
Files changed (89) hide show
  1. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/PKG-INFO +1 -1
  2. dv_flow_mgr-0.0.1.13468776985a1/docs/RundirLayout.md +9 -0
  3. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/Steps.md +18 -0
  4. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/ivpm.yaml +2 -0
  5. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/pyproject.toml +1 -1
  6. dv_flow_mgr-0.0.1.13468776985a1/src/dv_flow/mgr/expr_eval.py +50 -0
  7. dv_flow_mgr-0.0.1.13468776985a1/src/dv_flow/mgr/expr_parser.py +233 -0
  8. dv_flow_mgr-0.0.1.13468776985a1/src/dv_flow/mgr/parsetab.py +44 -0
  9. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/task.py +13 -104
  10. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/task_data.py +18 -0
  11. dv_flow_mgr-0.0.1.13468776985a1/src/dv_flow/mgr/task_exec_data.py +22 -0
  12. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow_mgr.egg-info/PKG-INFO +1 -1
  13. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow_mgr.egg-info/SOURCES.txt +6 -0
  14. dv_flow_mgr-0.0.1.13468776985a1/tests/unit/test_expr_eval.py +25 -0
  15. dv_flow_mgr-0.0.1.13468776985a1/tests/unit/test_expr_parser.py +16 -0
  16. dv_flow_mgr-0.0.1.13335470340a1/src/dv_flow/mgr/expr_parser.py +0 -38
  17. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/.github/workflows/ci.yml +0 -0
  18. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/.gitignore +0 -0
  19. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/.vscode/settings.json +0 -0
  20. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/LICENSE +0 -0
  21. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/README.md +0 -0
  22. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/KeyArchitecture.md +0 -0
  23. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/Makefile +0 -0
  24. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/Notes.md +0 -0
  25. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/Roadmap.md +0 -0
  26. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/Stages.md +0 -0
  27. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/TypesAndDefs.md +0 -0
  28. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/Usecases.md +0 -0
  29. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/conf.py +0 -0
  30. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/index.rst +0 -0
  31. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/intro.rst +0 -0
  32. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/quickstart.rst +0 -0
  33. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/docs/reference.rst +0 -0
  34. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/setup.cfg +0 -0
  35. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/__init__.py +0 -0
  36. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/__main__.py +0 -0
  37. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/cmds/cmd_run.py +0 -0
  38. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/fileset.py +0 -0
  39. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/fragment_def.py +0 -0
  40. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/out +0 -0
  41. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/package.py +0 -0
  42. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/package_def.py +0 -0
  43. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/package_import_spec.py +0 -0
  44. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/param_def.py +0 -0
  45. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/pkg_rgy.py +0 -0
  46. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/share/flow.json +0 -0
  47. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/std/fileset.py +0 -0
  48. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/std/flow.dv +0 -0
  49. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/std/message.py +0 -0
  50. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/std/task_null.py +0 -0
  51. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/task_def.py +0 -0
  52. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/task_graph_builder.py +0 -0
  53. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/task_graph_runner.py +0 -0
  54. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/task_graph_runner_local.py +0 -0
  55. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/task_impl_data.py +0 -0
  56. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/task_memento.py +0 -0
  57. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/task_output.py +0 -0
  58. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/type.py +0 -0
  59. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/type_def.py +0 -0
  60. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow/mgr/util.py +0 -0
  61. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow_mgr.egg-info/dependency_links.txt +0 -0
  62. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow_mgr.egg-info/entry_points.txt +0 -0
  63. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow_mgr.egg-info/requires.txt +0 -0
  64. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/src/dv_flow_mgr.egg-info/top_level.txt +0 -0
  65. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/examples/example1/example1.flow +0 -0
  66. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/system/test_depends.py +0 -0
  67. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/system/test_pkg_discovery.py +0 -0
  68. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/system/test_stdlib.py +0 -0
  69. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/__init__.py +0 -0
  70. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/fileset/test1/files1/file1_1.sv +0 -0
  71. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/fileset/test1/files1/file1_2.sv +0 -0
  72. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/fileset/test1/files2/file2_1.sv +0 -0
  73. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/fileset/test1/files2/file2_2.sv +0 -0
  74. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/fileset/test1/flow.dv +0 -0
  75. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/fileset/test1 copy/files1/file1_1.sv +0 -0
  76. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/fileset/test1 copy/files1/file1_2.sv +0 -0
  77. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/fileset/test1 copy/files2/file2_1.sv +0 -0
  78. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/fileset/test1 copy/files2/file2_2.sv +0 -0
  79. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/fileset/test1 copy/test1.dfs +0 -0
  80. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/proj1/proj1.dfs +0 -0
  81. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/proj2/proj2.dfs +0 -0
  82. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/data/proj3/proj3.dfs +0 -0
  83. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/test_data_merge.py +0 -0
  84. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/test_fileset.py +0 -0
  85. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/test_parse.py +0 -0
  86. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/test_pyclass.py +0 -0
  87. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/test_smoke copy.sav +0 -0
  88. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/test_smoke.py +0 -0
  89. {dv_flow_mgr-0.0.1.13335470340a1 → dv_flow_mgr-0.0.1.13468776985a1}/tests/unit/test_stdlib.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dv-flow-mgr
3
- Version: 0.0.1.13335470340a1
3
+ Version: 0.0.1.13468776985a1
4
4
  Summary: DV Flow Manager is a build system for silicon design
5
5
  Author-email: Matthew Ballance <matt.ballance@gmail.com>
6
6
  License: Apache License
@@ -0,0 +1,9 @@
1
+
2
+ rundir/
3
+ - info/
4
+ - task-execution database
5
+ - execution logs
6
+ - tasks/
7
+ - per-task execution directory
8
+ - only for tasks that require persistent outputs
9
+
@@ -40,6 +40,7 @@ Result Data
40
40
  - changed
41
41
  - memento
42
42
  - list of markers
43
+ - exit status (?)
43
44
  - Saves memento and markers for later inspection (central dir?)
44
45
  - Sets 'self' as source of parameter sets
45
46
  - Forms output data from
@@ -47,4 +48,21 @@ Result Data
47
48
  - list of parameter sets
48
49
 
49
50
  # Creating Task Parameters
51
+ -
52
+
53
+ # Need execution support for tasks
54
+ - Create parameters given the current inputs
55
+ - Need to follow inheritance
56
+ - Last (bottom-up) "value" wins
57
+ - Appends act bottom-up
58
+
59
+ - Task holds handles to input data from dependencies
60
+ -
61
+ - Make Task as simple as possible: scheduling item and place to store data
62
+
63
+ - Something needs to prepare inputs (likely runner)
64
+ - Locate
65
+ - Something needs to process result
66
+ - Save memento in central store (map of task-execution records)
67
+ - Organize with start/finish times, etc
50
68
  -
@@ -27,5 +27,7 @@ package:
27
27
  src: pypi
28
28
  - name: jq
29
29
  src: pypi
30
+ - name: ply
31
+ src: pypi
30
32
 
31
33
 
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "dv-flow-mgr"
8
- version = "0.0.1.13335470340a1"
8
+ version = "0.0.1.13468776985a1"
9
9
  dependencies = [
10
10
  'pydantic',
11
11
  'pyyaml',
@@ -0,0 +1,50 @@
1
+
2
+ import dataclasses as dc
3
+ from typing import Any, Callable, Dict, List
4
+ from .expr_parser import ExprVisitor, Expr, ExprBin, ExprBinOp, ExprCall, ExprId, ExprString, ExprInt
5
+
6
+ @dc.dataclass
7
+ class ExprEval(ExprVisitor):
8
+ methods : Dict[str, Callable] = dc.field(default_factory=dict)
9
+ variables : Dict[str, object] = dc.field(default_factory=dict)
10
+ value : Any = None
11
+
12
+ def eval(self, e : Expr):
13
+ self.value = None
14
+ e.accept(self)
15
+ return self.value
16
+
17
+ def visitExprId(self, e : ExprId):
18
+ if e.id in self.variables:
19
+ self.value = self.variables[e.id]
20
+ else:
21
+ raise Exception("Variable %s not found" % e.id)
22
+
23
+ def visitExprString(self, e : ExprString):
24
+ self.value = e.value
25
+
26
+ def visitExprBin(self, e):
27
+ e.lhs.accept(self)
28
+
29
+ if e.op == ExprBinOp.Pipe:
30
+ # Value just goes over to the rhs
31
+ e.rhs.accept(self)
32
+ elif e.op == ExprBinOp.Plus:
33
+ pass
34
+
35
+ def visitExprCall(self, e : ExprCall):
36
+ if e.id in self.methods:
37
+ # Need to gather up argument values
38
+ in_value = self.value
39
+ args = []
40
+ for arg in e.args:
41
+ self.value = None
42
+ arg.accept(self)
43
+ args.append(self.value)
44
+
45
+ self.value = self.methods[e.id](in_value, args)
46
+ else:
47
+ raise Exception("Method %s not found" % e.id)
48
+
49
+ def visitExprInt(self, e : ExprInt):
50
+ self.value = e.value
@@ -0,0 +1,233 @@
1
+ import dataclasses as dc
2
+ import enum
3
+ import ply.lex as lex
4
+ import ply.yacc as yacc
5
+ from typing import ClassVar, List
6
+
7
+ @dc.dataclass
8
+ class Expr(object):
9
+ def accept(self, v):
10
+ raise NotImplementedError("Expr.accept for %s" % str(type(sepf)))
11
+
12
+ @dc.dataclass
13
+ class ExprId(Expr):
14
+ id : str
15
+
16
+ def accept(self, v):
17
+ v.visitExprId(self)
18
+
19
+ class ExprBinOp(enum.Enum):
20
+ Pipe = enum.auto()
21
+ Plus = enum.auto()
22
+ Minus = enum.auto()
23
+ Times = enum.auto()
24
+ Divide = enum.auto()
25
+
26
+ @dc.dataclass
27
+ class ExprBin(Expr):
28
+ op : ExprBinOp
29
+ lhs : Expr
30
+ rhs : Expr
31
+
32
+ def accept(self, v):
33
+ v.visitExprBin(self)
34
+
35
+ @dc.dataclass
36
+ class ExprCall(Expr):
37
+ id : str
38
+ args : List[Expr]
39
+
40
+ def accept(self, v):
41
+ v.visitExprCall(self)
42
+
43
+ @dc.dataclass
44
+ class ExprString(Expr):
45
+ value : str
46
+
47
+ def accept(self, v):
48
+ v.visitExprString(self)
49
+
50
+ @dc.dataclass
51
+ class ExprInt(Expr):
52
+ value : int
53
+
54
+ def accept(self, v):
55
+ v.visitExprInt(self)
56
+
57
+ class ExprVisitor(object):
58
+ def visitExprId(self, e : ExprId):
59
+ pass
60
+
61
+ def visitExprBin(self, e : ExprBin):
62
+ e.lhs.accept(self)
63
+ e.rhs.accept(self)
64
+
65
+ def visitExprCall(self, e : ExprCall):
66
+ for arg in e.args:
67
+ arg.accept(self)
68
+
69
+ def visitExprString(self, e : ExprString):
70
+ pass
71
+
72
+ def visitExprInt(self, e : ExprInt):
73
+ pass
74
+
75
+ @dc.dataclass
76
+ class ExprVisitor2String(ExprVisitor):
77
+ _ret : str = ""
78
+ _idx : int = 0
79
+
80
+ @staticmethod
81
+ def toString(e : Expr):
82
+ v = ExprVisitor2String()
83
+ e.accept(v)
84
+ return v._ret
85
+
86
+ def visitExprId(self, e : ExprId):
87
+ self._ret += e.id
88
+
89
+ def visitExprBin(self, e):
90
+ e.lhs.accept(self)
91
+ self._ret += " "
92
+ self._ret += "op%d" % self._idx
93
+ self._idx += 1
94
+ self._ret += " "
95
+ e.rhs.accept(self)
96
+
97
+ def visitExprCall(self, e):
98
+ self._ret += e.id
99
+ self._ret += "("
100
+ for i, arg in enumerate(e.args):
101
+ if i > 0:
102
+ self._ret += ", "
103
+ arg.accept(self)
104
+ self._ret += ")"
105
+
106
+ def visitExprString(self, e):
107
+ self._ret += e.value
108
+
109
+ def visitExprInt(self, e):
110
+ self._ret += str(e.value)
111
+
112
+
113
+ class ExprParser(object):
114
+
115
+ _inst : ClassVar['ExprParser'] = None
116
+
117
+ def __init__(self):
118
+
119
+ # Build the lexer
120
+ self.lexer = lex.lex(module=self)
121
+ self.parser = yacc.yacc(module=self)
122
+
123
+ @classmethod
124
+ def inst(cls):
125
+ if cls._inst is None:
126
+ cls._inst = ExprParser()
127
+ return cls._inst
128
+
129
+ tokens = (
130
+ 'ID','NUMBER','COMMA',
131
+ 'PLUS','MINUS','TIMES','DIVIDE',
132
+ 'LPAREN','RPAREN','PIPE','STRING1','STRING2'
133
+ )
134
+
135
+ # Tokens
136
+
137
+ t_COMMA = r','
138
+ t_PLUS = r'\+'
139
+ t_MINUS = r'-'
140
+ t_TIMES = r'\*'
141
+ t_DIVIDE = r'/'
142
+ t_LPAREN = r'\('
143
+ t_RPAREN = r'\)'
144
+ t_ID = r'[a-zA-Z_][a-zA-Z0-9_]*'
145
+ t_PIPE = r'\|'
146
+ t_STRING2 = r'\'.*\''
147
+
148
+ def t_NUMBER(self, t):
149
+ r'\d+'
150
+ try:
151
+ t.value = ExprInt(int(t.value))
152
+ except ValueError:
153
+ print("Integer value too large %d", t.value)
154
+ t.value = ExprInt(0)
155
+ return t
156
+
157
+ def t_STRING1(self, t):
158
+ r'(\'|\")([^\\\n]|(\\.))*?(\'|\")'
159
+ t.value = t.value[1:-1].replace('\\"', '"').replace("\\'", "'").replace('\\n', '\n').replace('\\t', '\t').replace('\\\\', '\\')
160
+ return t
161
+
162
+ # Ignored characters
163
+ t_ignore = " \t"
164
+
165
+ def t_newline(self, t):
166
+ r'\n+'
167
+ t.lexer.lineno += t.value.count("\n")
168
+
169
+ def t_error(self, t):
170
+ print("Illegal character '%s'" % t.value[0])
171
+ t.lexer.skip(1)
172
+
173
+ precedence = (
174
+ ('left','PLUS','MINUS','PIPE'),
175
+ ('left','TIMES','DIVIDE'),
176
+ # ('right','UMINUS'),
177
+ )
178
+
179
+ def p_call(self, t):
180
+ """expression : ID LPAREN RPAREN
181
+ | ID LPAREN args RPAREN"""
182
+ t[0] = ExprCall(t[1], t[3] if len(t) == 5 else [])
183
+
184
+ def p_args(self, t):
185
+ """args : expression
186
+ | args COMMA expression"""
187
+ if len(t) == 2:
188
+ t[0] = [t[1]]
189
+ else:
190
+ t[0] = t[1]
191
+ t[0].append(t[3])
192
+
193
+ def p_expression_binop(self, t):
194
+ '''expression : expression PLUS expression
195
+ | expression MINUS expression
196
+ | expression TIMES expression
197
+ | expression PIPE expression
198
+ | expression DIVIDE expression'''
199
+ op_m = {
200
+ '+' : ExprBinOp.Plus,
201
+ '-' : ExprBinOp.Minus,
202
+ '*' : ExprBinOp.Times,
203
+ '|' : ExprBinOp.Pipe,
204
+ '/' : ExprBinOp.Divide
205
+ }
206
+ t[0] = ExprBin(op_m[t[2]], t[1], t[3])
207
+
208
+ def p_expression_group(self, t):
209
+ 'expression : LPAREN expression RPAREN'
210
+ t[0] = t[2]
211
+
212
+ def p_expression_number(self, t):
213
+ 'expression : NUMBER'
214
+ t[0] = t[1]
215
+
216
+ def p_expression_name(self, t):
217
+ 'expression : ID'
218
+ t[0] = ExprId(t[1])
219
+
220
+ def p_expression_string1(self, t):
221
+ 'expression : STRING1'
222
+ t[0] = ExprString(t[1])
223
+
224
+ def p_expression_string2(self, t):
225
+ 'expression : STRING2'
226
+ t[0] = ExprString(t[1])
227
+
228
+ def p_error(self, t):
229
+ print("Syntax error at '%s'" % t.value)
230
+
231
+ def parse(self, input):
232
+ return self.parser.parse(input, lexer=self.lexer)
233
+
@@ -0,0 +1,44 @@
1
+
2
+ # parsetab.py
3
+ # This file is automatically generated. Do not edit.
4
+ # pylint: disable=W,C,R
5
+ _tabversion = '3.10'
6
+
7
+ _lr_method = 'LALR'
8
+
9
+ _lr_signature = 'leftPLUSMINUSPIPEleftTIMESDIVIDECOMMA DIVIDE ID LPAREN MINUS NUMBER PIPE PLUS RPAREN STRING1 STRING2 TIMESexpression : ID LPAREN RPAREN \n | ID LPAREN args RPARENargs : expression \n | args COMMA expressionexpression : expression PLUS expression\n | expression MINUS expression\n | expression TIMES expression\n | expression PIPE expression\n | expression DIVIDE expressionexpression : LPAREN expression RPARENexpression : NUMBERexpression : IDexpression : STRING1expression : STRING2'
10
+
11
+ _lr_action_items = {'ID':([0,3,7,8,9,10,11,12,24,],[2,2,2,2,2,2,2,2,2,]),'LPAREN':([0,2,3,7,8,9,10,11,12,24,],[3,12,3,3,3,3,3,3,3,3,]),'NUMBER':([0,3,7,8,9,10,11,12,24,],[4,4,4,4,4,4,4,4,4,]),'STRING1':([0,3,7,8,9,10,11,12,24,],[5,5,5,5,5,5,5,5,5,]),'STRING2':([0,3,7,8,9,10,11,12,24,],[6,6,6,6,6,6,6,6,6,]),'$end':([1,2,4,5,6,14,15,16,17,18,19,22,23,],[0,-12,-11,-13,-14,-5,-6,-7,-8,-9,-1,-10,-2,]),'PLUS':([1,2,4,5,6,13,14,15,16,17,18,19,21,22,23,25,],[7,-12,-11,-13,-14,7,-5,-6,-7,-8,-9,-1,7,-10,-2,7,]),'MINUS':([1,2,4,5,6,13,14,15,16,17,18,19,21,22,23,25,],[8,-12,-11,-13,-14,8,-5,-6,-7,-8,-9,-1,8,-10,-2,8,]),'TIMES':([1,2,4,5,6,13,14,15,16,17,18,19,21,22,23,25,],[9,-12,-11,-13,-14,9,9,9,-7,9,-9,-1,9,-10,-2,9,]),'PIPE':([1,2,4,5,6,13,14,15,16,17,18,19,21,22,23,25,],[10,-12,-11,-13,-14,10,-5,-6,-7,-8,-9,-1,10,-10,-2,10,]),'DIVIDE':([1,2,4,5,6,13,14,15,16,17,18,19,21,22,23,25,],[11,-12,-11,-13,-14,11,11,11,-7,11,-9,-1,11,-10,-2,11,]),'RPAREN':([2,4,5,6,12,13,14,15,16,17,18,19,20,21,22,23,25,],[-12,-11,-13,-14,19,22,-5,-6,-7,-8,-9,-1,23,-3,-10,-2,-4,]),'COMMA':([2,4,5,6,14,15,16,17,18,19,20,21,22,23,25,],[-12,-11,-13,-14,-5,-6,-7,-8,-9,-1,24,-3,-10,-2,-4,]),}
12
+
13
+ _lr_action = {}
14
+ for _k, _v in _lr_action_items.items():
15
+ for _x,_y in zip(_v[0],_v[1]):
16
+ if not _x in _lr_action: _lr_action[_x] = {}
17
+ _lr_action[_x][_k] = _y
18
+ del _lr_action_items
19
+
20
+ _lr_goto_items = {'expression':([0,3,7,8,9,10,11,12,24,],[1,13,14,15,16,17,18,21,25,]),'args':([12,],[20,]),}
21
+
22
+ _lr_goto = {}
23
+ for _k, _v in _lr_goto_items.items():
24
+ for _x, _y in zip(_v[0], _v[1]):
25
+ if not _x in _lr_goto: _lr_goto[_x] = {}
26
+ _lr_goto[_x][_k] = _y
27
+ del _lr_goto_items
28
+ _lr_productions = [
29
+ ("S' -> expression","S'",1,None,None,None),
30
+ ('expression -> ID LPAREN RPAREN','expression',3,'p_call','expr_parser.py',160),
31
+ ('expression -> ID LPAREN args RPAREN','expression',4,'p_call','expr_parser.py',161),
32
+ ('args -> expression','args',1,'p_args','expr_parser.py',165),
33
+ ('args -> args COMMA expression','args',3,'p_args','expr_parser.py',166),
34
+ ('expression -> expression PLUS expression','expression',3,'p_expression_binop','expr_parser.py',174),
35
+ ('expression -> expression MINUS expression','expression',3,'p_expression_binop','expr_parser.py',175),
36
+ ('expression -> expression TIMES expression','expression',3,'p_expression_binop','expr_parser.py',176),
37
+ ('expression -> expression PIPE expression','expression',3,'p_expression_binop','expr_parser.py',177),
38
+ ('expression -> expression DIVIDE expression','expression',3,'p_expression_binop','expr_parser.py',178),
39
+ ('expression -> LPAREN expression RPAREN','expression',3,'p_expression_group','expr_parser.py',189),
40
+ ('expression -> NUMBER','expression',1,'p_expression_number','expr_parser.py',193),
41
+ ('expression -> ID','expression',1,'p_expression_name','expr_parser.py',197),
42
+ ('expression -> STRING1','expression',1,'p_expression_string1','expr_parser.py',201),
43
+ ('expression -> STRING2','expression',1,'p_expression_string2','expr_parser.py',205),
44
+ ]
@@ -25,7 +25,7 @@ import dataclasses as dc
25
25
  import logging
26
26
  from pydantic import BaseModel
27
27
  from typing import Any, Callable, ClassVar, Dict, List, Tuple
28
- from .task_data import TaskData
28
+ from .task_data import TaskData, TaskDataInput, TaskDataOutput, TaskDataResult
29
29
  from .task_memento import TaskMemento
30
30
 
31
31
  @dc.dataclass
@@ -180,112 +180,21 @@ class TaskCtorProxy(TaskCtor):
180
180
  class Task(object):
181
181
  """Executable view of a task"""
182
182
  name : str
183
- params : TaskParams
184
- srcdir : str = None
185
- session : 'TaskGraphRunner' = None
186
- basedir : str = None
187
- memento : TaskMemento = None
188
- depends : List['Task'] = dc.field(default_factory=list)
189
- output : Any = None
190
-
191
- # Implementation data below
192
- basedir : str = dc.field(default=None)
193
- rundir : str = dc.field(default=None)
194
- impl : str = None
195
- body: Dict[str,Any] = dc.field(default_factory=dict)
196
- impl_t : Any = None
197
-
198
- _log : ClassVar = logging.getLogger("Task")
199
-
200
- def init(self, runner, basedir):
201
- self.session = runner
202
- self.basedir = basedir
203
-
204
- def getMemento(self, T) -> TaskMemento:
205
- if os.path.isfile(os.path.join(self.rundir, "memento.json")):
206
- with open(os.path.join(self.rundir, "memento.json"), "r") as fp:
207
- try:
208
- data = json.load(fp)
209
- self.memento = T(**data)
210
- except Exception as e:
211
- self._log.critical("Failed to load memento %s: %s" % (
212
- os.path.join(self.rundir, "memento.json"), str(e)))
213
- os.unlink(os.path.join(self.rundir, "memento.json"))
214
- return self.memento
215
-
216
- def setMemento(self, memento : TaskMemento):
217
- self.memento = memento
218
-
219
- async def isUpToDate(self, memento) -> bool:
220
- return False
221
-
222
- async def do_run(self, session) -> TaskData:
223
- self._log.info("--> %s (%s) do_run - %d depends" % (
224
- self.name,
225
- str(type(self)),
226
- len(self.depends)))
227
-
228
- self.session = session
229
-
230
- if len(self.depends) > 0:
231
- deps_o = []
232
- for d in self.depends:
233
- dep_o = d.getOutput()
234
- if dep_o is None:
235
- raise Exception("Null output for %s" % d.name)
236
- deps_o.append(dep_o)
237
-
238
- input = TaskData.merge(deps_o)
239
- input.src = self.name
240
- input.deps[self.name] = list(inp.name for inp in self.depends)
241
- else:
242
- input = TaskData()
243
-
244
-
245
- # Mark the source of this data as being this task
246
- input.src = self.name
247
-
248
- self.init_rundir()
249
183
 
250
- self.output = await self.run(input)
184
+ # Need TaskDef
251
185
 
252
- if self.output is None:
253
- raise Exception("No output produced by %s" % self.name)
254
- result = TaskData()
255
-
256
- # Write-back the memento, if specified
257
- self.save_memento()
186
+ params : TaskParams # Might need to be set of instructions for building...
187
+ # This needs to be 'inside out' -- listed bottom to top
188
+ srcdir : str = dc.field(default=None)
189
+ rundir : str = dc.field(default=None)
190
+ depends : List['Task'] = dc.field(default_factory=list)
191
+ dependents : List['Task'] = dc.field(default_factory=list)
192
+ output : TaskDataOutput = dc.field(default=None)
258
193
 
259
- # Combine data from the deps to produce a result
260
- self._log.info("<-- %s (%s) do_run - %d depends" % (
261
- self.name,
262
- str(type(self)),
263
- len(self.depends)))
264
- return self.output
194
+ _log : ClassVar = logging.getLogger("Task")
265
195
 
266
- async def run(self, input : TaskData) -> TaskData:
196
+ async def run(self,
197
+ input : TaskDataInput,
198
+ runner : 'TaskGraphRunner') -> TaskDataResult:
267
199
  raise NotImplementedError("TaskImpl.run() not implemented")
268
-
269
- def init_rundir(self):
270
- if not os.path.isdir(self.rundir):
271
- os.makedirs(self.rundir)
272
-
273
- def save_memento(self):
274
- if self.memento is not None:
275
- with open(os.path.join(self.rundir, "memento.json"), "w") as fp:
276
- fp.write(self.memento.model_dump_json(indent=2))
277
-
278
- def getOutput(self) -> TaskData:
279
- return self.output
280
-
281
- def getField(self, name : str) -> Any:
282
- if name in self.__dict__.keys():
283
- return self.__dict__[name]
284
- elif name in self.__pydantic_extra__.keys():
285
- return self.__pydantic_extra__[name]
286
- else:
287
- raise Exception("No such field %s" % name)
288
-
289
-
290
-
291
200
 
@@ -27,6 +27,24 @@ from typing import Any, ClassVar, Dict, Set, List, Tuple
27
27
  from .fileset import FileSet
28
28
  from toposort import toposort
29
29
 
30
+ class TaskDataInput(BaseModel):
31
+ changed : bool
32
+ srcdir : str
33
+ rundir : str
34
+ params : Any
35
+ memento : Any
36
+
37
+ class TaskDataResult(BaseModel):
38
+ changed : bool
39
+ output : List[Any]
40
+ memento : Any
41
+ markers : List[Any]
42
+ status : int
43
+
44
+ class TaskDataOutput(BaseModel):
45
+ changed : bool
46
+ output : List[Any]
47
+
30
48
  class TaskDataParamOpE(enum.Enum):
31
49
  Set = enum.auto()
32
50
  Append = enum.auto()
@@ -0,0 +1,22 @@
1
+ import pydantic.dataclasses as dc
2
+ from pydantic import BaseModel
3
+ from typing import Any, Dict, List
4
+
5
+
6
+ class TaskExecData(BaseModel):
7
+ """Data from a single exection of a task"""
8
+ name : str
9
+ start : str
10
+ finish : str
11
+ status : int
12
+ memento : Any
13
+ markers : List[Any]
14
+
15
+ class FlowExecData(BaseModel):
16
+ """
17
+ Data from multiple tasks executions. 'info' holds information
18
+ across multiple flow invocations. 'tasks' holds the names of
19
+ tasks executed in the most-recent invocation.
20
+ """
21
+ info : Dict[str, TaskExecData] = dc.Field(default_factory=dict)
22
+ tasks : List[str] = dc.Field(default_factory=list)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dv-flow-mgr
3
- Version: 0.0.1.13335470340a1
3
+ Version: 0.0.1.13468776985a1
4
4
  Summary: DV Flow Manager is a build system for silicon design
5
5
  Author-email: Matthew Ballance <matt.ballance@gmail.com>
6
6
  License: Apache License
@@ -9,6 +9,7 @@ docs/KeyArchitecture.md
9
9
  docs/Makefile
10
10
  docs/Notes.md
11
11
  docs/Roadmap.md
12
+ docs/RundirLayout.md
12
13
  docs/Stages.md
13
14
  docs/Steps.md
14
15
  docs/TypesAndDefs.md
@@ -20,6 +21,7 @@ docs/quickstart.rst
20
21
  docs/reference.rst
21
22
  src/dv_flow/mgr/__init__.py
22
23
  src/dv_flow/mgr/__main__.py
24
+ src/dv_flow/mgr/expr_eval.py
23
25
  src/dv_flow/mgr/expr_parser.py
24
26
  src/dv_flow/mgr/fileset.py
25
27
  src/dv_flow/mgr/fragment_def.py
@@ -28,10 +30,12 @@ src/dv_flow/mgr/package.py
28
30
  src/dv_flow/mgr/package_def.py
29
31
  src/dv_flow/mgr/package_import_spec.py
30
32
  src/dv_flow/mgr/param_def.py
33
+ src/dv_flow/mgr/parsetab.py
31
34
  src/dv_flow/mgr/pkg_rgy.py
32
35
  src/dv_flow/mgr/task.py
33
36
  src/dv_flow/mgr/task_data.py
34
37
  src/dv_flow/mgr/task_def.py
38
+ src/dv_flow/mgr/task_exec_data.py
35
39
  src/dv_flow/mgr/task_graph_builder.py
36
40
  src/dv_flow/mgr/task_graph_runner.py
37
41
  src/dv_flow/mgr/task_graph_runner_local.py
@@ -59,6 +63,8 @@ tests/system/test_pkg_discovery.py
59
63
  tests/system/test_stdlib.py
60
64
  tests/unit/__init__.py
61
65
  tests/unit/test_data_merge.py
66
+ tests/unit/test_expr_eval.py
67
+ tests/unit/test_expr_parser.py
62
68
  tests/unit/test_fileset.py
63
69
  tests/unit/test_parse.py
64
70
  tests/unit/test_pyclass.py
@@ -0,0 +1,25 @@
1
+
2
+ import pytest
3
+ from dv_flow.mgr.expr_parser import ExprParser, ExprVisitor2String
4
+ from dv_flow.mgr.expr_eval import ExprEval
5
+
6
+ def test_smoke():
7
+ content = "sum(1, 2, 3, 4)"
8
+
9
+ def sum(in_value, args):
10
+ ret = 0
11
+ for arg in args:
12
+ ret += int(arg)
13
+ return ret
14
+
15
+ eval = ExprEval()
16
+ eval.methods["sum"] = sum
17
+
18
+ parser = ExprParser()
19
+ expr = parser.parse(content)
20
+ result = eval.eval(expr)
21
+
22
+ assert result == 10
23
+
24
+
25
+
@@ -0,0 +1,16 @@
1
+ import pytest
2
+ from dv_flow.mgr.expr_parser import ExprParser, ExprVisitor2String
3
+
4
+
5
+ def test_smoke():
6
+ # content = "in | jq('.[] | select(.name == \"foo\")') | out"
7
+ content = "in | jq(\".[] | select()\") | out(a, b) | out()"
8
+
9
+ parser = ExprParser()
10
+ expr = parser.parse(content)
11
+ print("Expr: %s" % ExprVisitor2String.toString(expr))
12
+
13
+ expr = parser.parse(content)
14
+ print("Expr: %s" % ExprVisitor2String.toString(expr))
15
+
16
+
@@ -1,38 +0,0 @@
1
- import dataclasses as dc
2
- import enum
3
-
4
- class TokenKind(enum.Enum):
5
- ID = enum.auto()
6
-
7
- @dc.dataclass
8
- class Expr(object):
9
- kind : TokenKind = TokenKind.ID
10
-
11
- class ExprId(Expr):
12
- id : str
13
-
14
- def __post_init__(self):
15
- self.kind = TokenKind.ID
16
-
17
- class ExprPipe(Expr):
18
- lhs : Expr
19
- rhs : Expr
20
-
21
- def __post_init__(self):
22
- self.kind = TokenKind.ID
23
-
24
-
25
-
26
- class ExprParser(object):
27
-
28
- def __init__(self, input):
29
- self.input = input
30
-
31
- def __iter__(self):
32
- return self
33
-
34
- def __next__(self):
35
-
36
- self.expr = expr
37
- self.tokens = []
38
- self.pos = 0