Commit Graph

47 Commits

Author SHA1 Message Date
James Shubin
4b0cdf9123 lang: types, engine: graph: Support pointer interfaces
If we have rare, but special *interface{} values in resource structs, we
should be able to handle them normally. It's really not recommended that
you use these unless you know exactly why they are useful.
2023-11-18 13:35:52 -05:00
James Shubin
1c9fdc79c0 engine: util: Add a workaround for printing special resources
This let's our tests compare strings of interface fields!
2023-11-18 13:35:52 -05:00
James Shubin
b048b2684b engine, lang: Allow resources with a field of type interface
This lets us add a resource that has an implementation with a field
whose type is determined at compile time. This let's us write more
flexible resources.

What's missing is additional type checking so that we guarantee that a
specific resource doesn't change types during run-time.
2023-11-12 17:25:03 -05:00
James Shubin
e38f3cc12c lang: types: Let the fancy TypeOf method match interfaces
This adds the functionality to match on interface kinds.
2023-11-12 16:14:38 -05:00
James Shubin
efc5237265 lang: types: Improve error handling of value code
We can give a bit more feedback and try and also catch a rare scenario.
2023-11-12 15:24:16 -05:00
James Shubin
3b46e88734 lang: types: Improve docs for New and initialize the list
If we use this to generate a zero value, we want to make sure it's
completely initialized in case we use it subsequently. We also improve
the docs at the same time.
2023-10-17 15:21:18 -04:00
James Shubin
0f99bfe7c4 lang: types: Add full func value
This needs to be in a separate package for now due to import cycles.

Co-authored-by: Samuel Gélineau <gelisam@gmail.com>
2023-09-25 18:51:07 -04:00
James Shubin
dbba49540e lang: types: Export the base value for others
This lets others implement this more easily.
2023-09-25 18:51:03 -04:00
James Shubin
5440ef7eb2 lang: types: Misc function changes
This will probably change up again in the future, but this is what we
need for now to make lambdas work.

Co-authored-by: Samuel Gélineau <gelisam@gmail.com>
2023-09-25 18:50:53 -04:00
James Shubin
7f46bcef61 lang: types: Loop in deterministic order
This makes some traces and reproducing of bugs slightly more
deterministic.
2023-09-25 18:48:38 -04:00
James Shubin
4fd90b5d52 lang: types: Avoid a panic if it's not settable
We should check this for safety. An error is better than a panic. If we
try to set an unexported field, this would panic. We should prevent
being able to even type unify that though!
2023-09-25 18:48:33 -04:00
James Shubin
6c0775ba59 engine: resources: Consider passing in funcs if possible
Let this sit in the test resource for now.
2023-09-04 16:33:05 -04:00
James Shubin
3fb75707e7 lang: types: We should use the platform-dependent int instead
This could be a 32 or 64 bit sized int depending on arch.
2023-08-28 15:54:36 -04:00
James Shubin
c1850e0e20 engine: resources, lang: Set resource fields more accurately
There were some bugs about setting resource fields that were structs
with various fields. This makes things more strict and correct. Now we
check for duplicate field names earlier (duplicates due to identical
aliases) and we also don't try and set private fields, or incorrectly
set partial structs.

Most interestingly, this also cleans up all of the resources and ensures
that each one has nicer docs and a clear struct tag for fields that we
want to use in mcl. These are mandatory now, and if you're missing the
tag, then we will ignore the field.
2023-08-26 01:11:50 -04:00
James Shubin
13b6b9de60 lang: types: Print the full function args
This makes it easier to see logs, but more importantly copy (well the
copy hack) doesn't erase arg names anymore.
2023-06-25 12:25:44 -04:00
James Shubin
a7624a2bf9 legal: Happy 2023 everyone...
Done with:

ack '2022+' -l | xargs sed -i -e 's/2022+/2023+/g'

Checked manually with:

git add -p

Hello to future James from 2024, and Happy Hacking!
2023-03-05 18:31:52 -05:00
James Shubin
3cea422365 legal: Happy 2022 everyone...
Done with:

ack '2021+' -l | xargs sed -i -e 's/2021+/2022+/g'

Checked manually with:

git add -p

Hello to future James from 2023, and Happy Hacking!
2022-08-05 23:06:27 -04:00
James Shubin
784d15b012 all: Misc housekeeping for new golang versions 2022-08-04 14:16:33 -04:00
James Shubin
5927a54208 docs: Improve autogenerate godoc
There were a bunch of packages that weren't well documented. With the
recent split up of the lang package, I figured it would be more helpful
for new contributors who want to learn the structure of the project.
2021-10-26 00:12:18 -04:00
James Shubin
b3d1ed9e65 lang: funcs: core: math: Add a fortytwo function
This is mainly meant as a useful test case, but might as well have it be
fun too. As an aside, it taught me a surprising result about the %v verb
in printf, and we'll have to decide if it's an issue we care about.

https://github.com/golang/go/issues/46118

The interesting thing about this method is that it uses the simplepoly
API but has no input args-- only the output types are different. If it
had identical types in the input args, that might also have been
interesting, but it's more rare to have none. Hopefully this exercises
our type unification logic.
2021-05-12 03:30:25 -04:00
Joe Groocock
83c5ab318b lang: types: Clear map/list types during Into()
Map and list types are now unconditionally initialised during an Into()
call to ensure that the only data within them after the operation is
that added by the Into() function.

Prior to this change, map/list types would likely not be cleared prior
to the data being inserted into them with a few exceptions. Nil
pointers or maps/lists that were not sufficient in capacity would be
reinitialised and used to replace the existing backing data store. In
some cases this wouldn't occur meaning any residual data existing in the
container before the Into() call could persist after the data copy
completes. This behaviour is wildly inconsistent and not ideal in the
vast majority of cases. It should be assumed that the Into() call will
preserve nothing and always produce a consistent and deterministic
output.

Signed-off-by: Joe Groocock <me@frebib.net>
2021-05-05 10:41:48 +01:00
James Shubin
5f0c6e5102 lang: types: Add extra ValueOf test
Just to double check weird behaviours of the golang reflect lib.
2021-05-04 06:26:33 -04:00
Joe Groocock
29f1c6f50e lang: types: Fix ValueOf() panic with nil pointer values
Some forms of reflect.Value can cause ValueOf() to panic when there is a
nil pointer somewhere within the reflect.Value, whether that be a
container type like a struct, list or map, or just a raw nil pointer.

In these cases, ValueOf() attempted to dereference the pointer without
ever checking if it was nil. mgmt lang doesn't have pointers of any
kind, so these Golang values cannot be represented in mcl types in the
current form so return a helpful error to the user.

Signed-off-by: Joe Groocock <me@frebib.net>
2021-05-04 06:26:23 -04:00
James Shubin
44e1e41266 lang: types: Improve documentation for ValueOf functions
A reminder that nil's in golang don't map to anything in mcl.
2021-05-04 05:27:07 -04:00
James Shubin
33fda8605a lang: types: Add new ValueOf tests
Hopefully this makes all of this a bit more obvious.
2021-05-04 04:27:33 -04:00
Joe Groocock
6b14c9bea4 lang: Map Go struct fields using lang struct tag
Converting a reflect.Type of KindStruct did not respect the `lang` tag
on struct fields incidating how fields from mcl structs should be mapped
even though resource field names did. This patch should allow structs
with mapped fields to be respected.

Signed-off-by: Joe Groocock <me@frebib.net>
2021-02-06 16:57:01 +00:00
Joe Groocock
52897cc16c lang: Implement Into() to set types.Value from reflect.Value
Into() mutates a given reflect.Value and sets the data represented by
the types.Value into the storage represented by the reflect.Value.

Into() is the opposite to ValueOf() which converts reflect.Value into
types.Value, and in theory they should be (almost) bijective with some
edge case exceptions where the conversion is lossy.

Simply, it replaces reflect.Value.Set() in the broad case, giving finer
control of how the reflect.Value is modified and how the data is set.
types.Value.Value() is now also a redundant function that achieves the
same outcome as Into(), but with less type specificity.

Signed-off-by: Joe Groocock <me@frebib.net>
2021-02-06 16:57:00 +00:00
Joe Groocock
c950568f1b lang: Move StructTag const into lang/types
This constant value is strongly tied to the language, and little to do
with the engine. Move the definition into the lang/types package to
prevent circular imports between lang/types and engine/util.

Signed-off-by: Joe Groocock <me@frebib.net>
2021-02-06 16:56:57 +00:00
Joe Groocock
845d7ff188 lang: Fix panic in lang/types/ValueOf() for Struct
Replace use of reflect.Value.Len() with NumField() which is intended to
return the number of fields in reflected Struct value.

Len should only be used for Array, Chan, Map, Slice and String types.

Add some trivial sanity check tests for ValueOf() for the simple and
complex container types.

Signed-off-by: Joe Groocock <me@frebib.net>
2021-01-31 23:10:16 +00:00
James Shubin
336a38081a legal: Happy 2021 everyone...
Done with:

ack '2020+' -l | xargs sed -i -e 's/2020+/2021+/g'

Checked manually with:

git add -p

Hello to future James from 2022, and Happy Hacking!
2021-01-31 16:52:46 -05:00
James Shubin
f67ad9c061 test: Add a check for too long or badly reflowed docstrings
This ensures that docstring comments are wrapped to 80 chars. ffrank
seemed to be making this mistake far too often, and it's a silly thing
to look for manually. As it turns out, I've made it too, as have many
others. Now we have a test that checks for most cases. There are still a
few stray cases that aren't checked automatically, but this can be
improved upon if someone is motivated to do so.

Before anyone complains about the 80 character limit: this only checks
docstring comments, not source code length or inline source code
comments. There's no excuse for having docstrings that are badly
reflowed or over 80 chars, particularly if you have an automated test.
2020-01-25 04:43:33 -05:00
James Shubin
2648fb1bb1 legal: Happy 2020 everyone...
Done with:

ack '2019+' -l | xargs sed -i -e 's/2019+/2020+/g'

Checked manually with:

git add -p

Hello to future James from 2021, and Happy Hacking!
2020-01-03 20:08:37 -05:00
James Shubin
f53376cea1 lang: Add function values and lambdas
This adds a giant missing piece of the language: proper function values!
It is lovely to now understand why early programming language designers
didn't implement these, but a joy to now reap the benefits of them. In
adding these, many other changes had to be made to get them to "fit"
correctly. This improved the code and fixed a number of bugs.
Unfortunately this touched many areas of the code, and since I was
learning how to do all of this for the first time, I've squashed most of
my work into a single commit. Some more information:

* This adds over 70 new tests to verify the new functionality.

* Functions, global variables, and classes can all be implemented
natively in mcl and built into core packages.

* A new compiler step called "Ordering" was added. It is called by the
SetScope step, and determines statement ordering and shadowing
precedence formally. It helped remove at least one bug and provided the
additional analysis required to properly capture variables when
implementing function generators and closures.

* The type unification code was improved to handle the new cases.

* Light copying of Node's allowed our function graphs to be more optimal
and share common vertices and edges. For example, if two different
closures capture a variable $x, they'll both use the same copy when
running the function, since the compiler can prove if they're identical.

* Some areas still need improvements, but this is ready for mainstream
testing and use!
2019-07-17 00:27:09 -04:00
James Shubin
4c6d304e60 lang: types: Improve ComplexCmp function
This improves the ComplexCmp function so that it can compare partial
types to variant types. As a result of this improvement, it actually
ended up simplifying the code significantly. This also added a test
suite for this function. This fix was important for tricky type
unification problems.
2019-07-12 16:46:08 -04:00
James Shubin
17fd625f7f lang: types: Workaround stringer regression in golang 1.11
Here's a fix for another golang regression in 1.11.x which wasn't needed
before! More info in: https://github.com/golang/go/issues/31843
2019-05-05 09:32:04 -04:00
James Shubin
2f7e202f40 lang, lang: types: Add automatic stringer generation
It's more useful if we know the string representation of Kind's.
2019-05-05 09:32:03 -04:00
James Shubin
310239e707 lang: types: Remove unnecessary prefix in generated kinds
This will make displayed errors cleaner.
2019-05-05 09:30:13 -04:00
James Shubin
07f542b4d7 legal: Happy 2019 everyone...
Done with:

ack '2018+' -l | xargs sed -i -e 's/2018+/2019+/g'

Checked manually with:

git add -p

Hello to future James from 2020, and Happy Hacking!
2019-03-24 15:08:50 -04:00
James Shubin
753d1104ef util: Port all multierr code to new errwrap package
This cleans things up and simplifies a lot of the code. Also it's easier
to just import one error package when needed.
2019-03-12 16:51:37 -04:00
James Shubin
880652f5d4 util: Port all code to new errwrap package
This should keep things more uniform.
2019-03-12 16:49:01 -04:00
James Shubin
de1691665f lang: funcs: Add live function stream test infrastructure
This adds the ability to test that functions return the expected
streams, and to model this behaviour over time. This is done via a
"timeline" which runs an ordered list of actions that can both push new
values into the function stream, and wait and expect particular outputs.
Hopefully this will make our function implementations more robust!
2019-03-06 07:09:39 -05:00
James Shubin
48beea3884 test: Clean up and improve golang tests
This adds some consistency to the tests and properly catches difficult
scenarios in some of the lexparse tests.
2018-12-20 21:21:30 -05:00
James Shubin
c4b97fadcc lang: Update map type definition to include a prefix
It turns out that some planned additions to the parser make it so that
the map type definition can be ambiguous. As a result, this patch
updates the definition so that the map definition is not confused with
an open curly bracket anywhere.

Thanks to pestle and stbenjamin for their help understanding yacc!
2018-06-18 16:06:23 -04:00
James Shubin
22c0ff3cf5 test: Improve golang tests with root and disabling cache
This allows golang tests to be marked as root or !root using build tags.
The matching tests are then run as expected using our test runner.

This also disables test caching which is unfriendly to repeated test
running and is an absurd golang default to add.

Lastly this hooks up the testing verbose flag to tests that accept a
debug variable.

These tests aren't enabled on travis yet because of how it installs
golang.
2018-05-09 13:44:01 -04:00
James Shubin
80784bb8f1 lang: types, funcs: Add simple polymorphic function API
This adds a simple API for adding static, polymorphic, pure functions.
This lets you define a list of type signatures and the associated
implementations to overload a particular function name. The internals of
this API then do all of the hard work of matching the available
signatures to what statically type checks, and then calling the
appropriate implementation.

While this seems as if this would only work for function polymorphism
with a finite number of possible types, while this is mostly true, it
also allows you to add the `variant` "wildcard" type into your
signatures which will allow you to match a wider set of signatures.

A canonical use case for this is the len function which can determine
the length of both lists and maps with any contained type. (Either the
type of the list elements, or the types of the map keys and values.)

When using this functionality, you must be careful to ensure that there
is only a single mapping from possible type to signature so that the
"dynamic dispatch" of the function is unique.

It is worth noting that this API won't cover functions which support an
arbitrary number of input arguments. The well-known case of this,
printf, is implemented with the more general function API which is more
complicated.

This patch also adds some necessary library improvements for comparing
types to partial types, and to types containing variants.

Lastly, this fixes a bug in the `NewType` parser which parsed certain
complex function types wrong.
2018-02-25 02:17:13 -05:00
James Shubin
837388ae4e lang: types, funcs: Add simple function API
This patch adds a simple function API for writing simple, pure
functions. This should reduce the amount of boilerplate required for
most functions, and make growing a stdlib significantly easier. If you
need to build more complex, event-generating functions, or statically
polymorphic functions, then you'll still need to use the normal API for
now.

This also makes all of these pure functions available automatically
within templates. It might make sense to group these functions into
packages to make their logical organization easier, but this is a good
enough start for now.

Lastly, this added some missing pieces to our types library. You can now
use `ValueOf` to convert from a `reflect.Value` to the corresponding
`Value` in our type system, if an equivalent exists.

Unfortunately, we're severely lacking in tests for these new types
library additions, but look forward to growing some in the future!
2018-02-21 21:32:31 -05:00
James Shubin
b19583e7d3 lang: Initial implementation of the mgmt language
This is an initial implementation of the mgmt language. It is a
declarative (immutable) functional, reactive, domain specific
programming language. It is intended to be a language that is:

* safe
* powerful
* easy to reason about

With these properties, we hope this language, and the mgmt engine will
allow you to model the real-time systems that you'd like to automate.

This also includes a number of other associated changes. Sorry for the
large size of this patch.
2018-01-20 08:09:29 -05:00