Giter VIP home page Giter VIP logo

ablec's Introduction

AbleC: Reliably composable language extensions for C

AbleC is a C11 compiler front-end that supports modular definition and reliable composition of language extensions. AbleC is implemented using Silver.

Authors

Past contributors include Ted Kaminski.

Releases

  • Release 0.1.0: made in April, 2020

Related publications

ableC is the topic of our paper "Reliable and Automatic Composition of Language Extensions to C: The ableC Extensible Language Framework" that appeared at OOPSLA 2017. See DOI http://doi.acm.org/10.1145/3138224.

Getting started

Setup instructions and tips on getting started

Websites and repositories

Software downloads, documentation, and related papers are available on the Melt group web site at http://melt.cs.umn.edu/.

Actively-developed versions of this software are available on GitHub at https://github.com/melt-umn/ableC.

Archival versions of this software are permanently available on the Data Repository of the University of Minnesota at https://doi.org/10.13020/D6VQ25.

Other software and artifacts are also archived there and can be reached from this persistent link: http://hdl.handle.net/11299/206558.

Acknowledgements

We are very grateful to the National Science Foundation, the McKnight Foundation, DARPA, the University of Minnesota, and IBM for funding different aspects of our research and the development of Silver and Copper.

Licensing

ableC is distributed under the GNU Lesser General Public License. See the file LICENSE for details of this licenses. More information can be found at http://www.gnu.org/licenses/.

ablec's People

Contributors

200sc avatar 602p avatar counc009 avatar ericvanwyk avatar hypnoticoxbow avatar krame505 avatar remexre avatar tedinski avatar traviscarlson avatar unironically avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ablec's Issues

Builtin definitions

/usr/include/x86_64-linux-gnu/bits/byteswap.h wants the __builtin_bswap32 and __builtin_bswap64 builtins to be defined if we're on a recent-ish version of GCC. Because we invoke cpp without passing any flags to tell it otherwise, we appear to be on GCC 5.4.1 (according to echo | cpp -dM | grep GNUC).

We should define these builtins.

Missing checks for L-values in assignment

AbleC currently allows assignment to non L-values. As a very simple example, it allows code such as
1 = 2;
which is obviously not valid C.
The solution to this would involve adding a new attribute to expressions
synthesized attribute isLValue::Boolean occurs on Expr;
to test if something is an L-value. This would then be checked in assignments and an error would be raised if the left hand side is not an L-value.

Get rid of parenType, parenTypeExpr

These productions are used to preserve parentheses written as part of a type expression, and don't have any semantic meaning. As far as I can tell, parens are only needed in type expressions for function pointers? Is there a reason we can't just add these parens when needed while pretty-printing the type expression, getting rid of these productions? This was a point of confusion for me in trying to get function pointers working.

OctConstant typo

Most of the OctConstant productions near the bottom of concretesyntax/Expr.sv seems to have typos in that "integerConstant" should probably be "octIntegerConstant" instead.

Fix or remove nestedFunctionDecl

I have no idea why this even exists (actually, I might have added it back when I was first working on closures, before I knew what I was doing), but it is totally useless right now since any analysis defined here would be incoherent.

If we want to let extensions define analyses differently on regular and nested functions, this should become non-forwarding, and the entire contents duplicated from functionDecl. However, I have yet to see a case where this would actually be useful, so the production should probably just be removed for now, and any uses in the ableC concrete syntax replaced by functionDecl.

Might be a good task for somebody new who wants to gain confidence in refactoring ableC?

New MWDA error in host

Errors for edu:umn:cs:melt:ableC:abstractsyntax
 [edu.umn.cs.melt.ableC/abstractsyntax/Decls.sv]
Decls.sv:322:87: warning: Attribute section (.pp) requires attributes not know to be on 'SpecialSpecifier': env, returnType

This was a missing and recently introduced check in the Silver MWDA.

Missing type checking for object initializers

Currently we have none. We should do this.

This would involve creating some sort of data structure including the names/positions and types of fields in a (possibly nested) struct/union. This would be made available on RefIdItem, and passed down the Initializer, etc. tree in order to compute errors.

Missing type-checking for binary operators

Currently we aren't doing any error checking on binary operators other than AssignOps (and these lack checking for things such as += for whether addition is valid).

I'm not sure what the best way to structure this would be - on all the BinOp productions, just check if top.typerep is errorType() and top.lop.typerep and top.rop.typerep are not, and if so raise an error? @tedinski what was the original plan for this?

Refactor concrete syntax to permit type expressions that disallow struct/enum/union declarations

This is primarily for melt-umn/ableC-closure#3, but could be useful for extensions in general.
In some places in C++ (e.g. lambdas) type expressions that aren't a struct/enum/union declaration are permitted to be followed by a {. Currently in ableC we don't segregate type expressions in this way, so it isn't possible for extensions to mimic such C++ syntax.
I propose that we split TypeSpecifier_c into 2 nonterminals:

  • DefTypeSpecifier_c contains only struct, enum and union definition (but not tag reference) type expressions. The follow set for this does not contain '{'
  • BasicTypeSpecifier_c contains everything else in TypeSpecifier_c. The follow set here would be seeded with '{'.

The TypeSpecifier_c nonterminal as-is would contain productions to both of these new nonterminals. We would introduce a new BasicSpecifierQualifierList_c mirroring SpecifierQualifierList_c, but instead with BasicTypeSpecifier_c, while SpecifierQualifierList_c would remain unchanged. Extensions wishing to use a type expression followed by '{' (such as closure) would then use BasicSpecifierQualifierList_c. Extensions defining new type expressions that end in braces (such as algebraic datatypes) would now define their productions on DefTypeSpecifier_c, while all other new type expressions (such as the closure type expression) would be defined on BasicTypeSpecifier_c.

Thoughts? If approved I might attempt this over the weekend.

Potential Need for new lValue attribute in ableC

I'm working on a Tensor Algebra Compiler extension for ableC with Eric. I have an overload of function calls, and this is used to access elements from the tensor, but based on how the tensors are stored I have a situation where the forwarding code depends on whether the Expr appears as an lValue or rValue. The Expr nonterminal has an isLValue attribute, but this attribute doesn't behave as a check of whether the Expr is being used as an lValue or rValue. Such an attribute would have to be an inherited attribute, which is why such an attribute can't be added in an extension, as it causes MWDA analysis to fail.

Eric asked me to create this so we can discuss whether this is something that should be added to the ableC, now that we have an example where this matters, or whether there is another known workaround. Thanks.

Extensions can forward to an AST containing errors in types that are uncaught

When forwarding to directTypeExpr, there is no checking done to ensure that the parameter type is actually valid (e.g. for typedefType, that the parameter name is a valid type). This can result in us generating non-compiling c code without raising errors. This in theory shouldn't cause issues for the end user assuming extensions are bug-free, but can be an issue for the extension writer, as it points to a bug in the host language when there actually isn't.

One way of fixing this may be to add attributes on Type to translate back to a BaseTypeExpr and TypeModifierExpr (similar to .lpp and .rpp), and have directTypeExpr forward to a production wrapping the result of this transformation instead. This would also greatly simplify handling lifting globalDecls from Type, since then we would no longer be considering Type part of the bottom-level host AST.

Incoming flow errors

I'm in the process of finalizing the added pattern matching support for the flow analysis. I used to think this wouldn't lead to new errors, but I discovered there's a missing piece of the analysis along the way.

I tried the (currently in-progress) analysis and it so far only found one new problem:

Errors for edu:umn:cs:melt:ableC:abstractsyntax:substitution
 [./edu.umn.cs.melt.ableC/abstractsyntax/substitution/Attribute.sv]
Attribute.sv:60:2: warning: Synthesized equation 'substituted' exceeds flow type with dependencies on env, returnType

This is the relevant production:

aspect production appliedAttrib
top::Attrib ::= n::AttribName  e::Exprs
{
  local substitutions::Substitutions = top.substitutions;
  substitutions.nameIn =
    case n, e of
      attribName(n), consExpr(stringLiteral(s), nilExpr()) ->
        ...
    | _, _ -> ""
    end;
  top.substituted =
    ... substitutions.refIdSub ...;
}

Notice we're pattern matching on e, which means we must be able to evaluate the forwarding equation of any expressions, which presumably requires env, returnType.

I believe this was missed before because we're pattern matching on Exprs outermost which possibly has a forwarding flow type that's empty, so the outer pattern match was OK. Then matching on the inner child erroneously believed it had a proper Decorated Expr and assumed the ref set. But that's not a safe assumption without checking.

So with it now "looking through" pattern matching, it sees that the inner child only has env if the outer has env, so it accurately emits the dependency, which causes the flow type for substituted to go awry.

Anyway, I think this implementation isn't done yet, but already it's found one new flow error. Let's hope it doesn't find any more. Just a heads-up.

ADT extension crashes when dealing with non-pointer ADTs

The ADT extension seems to be crashing when matching on a dereferenced ADT. The following is a (mostly) minimal test case:

typedef datatype Node Node;

datatype Node {
  Leaf (int);
};

int main() {
  Node n = *Leaf(4);

  match (n) {
    Leaf (i): ;
  };
}

It is also unclear how to nicely handle non-pointer ADTs; We allow the user to create them and pass them around, but they always have to be written as a pointer and be used as a pointer to do anything with them. Would it make sense to automatically take the address when a match is performed on a non-pointer? Otherwise we should consider making datatypes always pointers behind the scenes, and just hiding this from the user. Also, why are ADTs pointers at the top level, anyway?

Type and closed nonterminals

This is something that I have been thinking about for quite a while, and I think I finally came up with something workable. Sorry about the length, I just wanted to make a complete brain-dump of my thoughts on this for discussion...

Background

Currently, extensions may introduce new types (as in the sense of data or newtype in Haskell), but only by forwarding to a new struct/enum/union type. In order to check whether something is an extension type (and possibly extract the values of type parameters), since we are not allowed to directly match on the extension type production due to maintain coherence, we must resort to cumbersome methods (e.g. as seen in the closure extension.) It seems that we could benefit by adding a method of introducing new, non-forwarding productions into the type hierarchy.

Note that deciding to use nonterminals vs. closed nonterminals typically involves some kind of tradeoff - either we can allow arbitrary analyses and restrict new variants to be expressed in terms of the host, or allow arbitrary variants and restrict analyses. However, in this case, the host language already allows arbitrary variants of types, which must be given some form of default treatment by the type system and any added analyses. So permitting arbitrary new types to be introduced by extensions doesn't impose any additional restrictions, since any new analyses on types would have a default in the form of the value given to structs.

As another advantage, having some form of closed types would permit us to return to something along the lines of our prior, somewhat less confusing method of overloading based on higher-order dispatch attributes on types, without suffering any interference issues. Although the most basic rule for coherence on closed nonterminals states that the value for a new attribute on any production should be equivalent to the default value, we can and have found other situations that are exceptions to this, such as in the case of what we did for Def in order to simulate a non-homogeneous collection structure. In order to evaluate whether a particular case is non-interfering, we simply need to ask if any glue code would be required for it to compose.

If extension E1 were to introduce a new overload attribute A on some form of closed type nonterminal, with a default equation of nothing(), and extension E2 were to introduce a new production P on this nonterminal, then the default equation for A on P should be nothing(), since E1 knows nothing about E2 and should not overload that type. Then the default and expected values are the same, so no glue code is required. This is true in general for this type of attribute, and I hope to prove this more rigorously after reading that section of Ted's thesis, although it should be somewhat intuitively clear.

Note that some analyses do not have this property of having a valid default for productions in independent extensions, such as an equality test via isEqualTo/isEqual-type attributes, and would need to be included in the host. However, this is the only example of which I can think that would would be affected by this change, due to the presence of struct/enum/union types. For example, adding a new transformation on types similar to lifted would just leave new extension types unchanged as is the case with structs right now, and currently an analysis for if a type contains a pointer isn't possible since we can`t look inside structs.

Proposal

Although theoretically an option, closing the entire Type nonterminal would require major changes in lots of places and could complicate how we deal with interconverting type expressions and types, due to C's division into base type and type modifier expressions.

A better option would be to add a new closed nonterminal, ExtType (for 'extension type' or 'external type' - whatever), and a new production extType :: (Type ::= Qualifiers ExtType). ExtType would have almost all the same attributes as Type, although most of these would have defaults. In addition, it would have isEqualTo/isEqual attributes for checking equality, and the qualifiers would be passed in from extType via an inherited attribute.

Since every type has a corresponding type expression, extType would have a corresponding BaseTypeExpr production, extTypeExpr :: (BaseTypeExpr ::= Qualifers ExtType). The transformation between these would be trivial, and host and pp on extTypeExpr would come directly from ExtType, which would be explicitly defined in every extension ExtType production. extTypeExpr would also have no errors, defs, freeVariables, globalDecls, or typeModifiers.

Then, for an extension to introduce a new type, it would introduce a new, non-forwarding production on ExtType, defining at least the equations for pp, host, and isEqual. The extension would also define a BaseTypeExpr production forwarding to extTypeExpr wrapping the newly defined ExtType. Note that extensions could still also define normal, forwarding Type productions that are equivalent to host types, as we do now.

Since they would have similar semantics, TagTypes (consisting of enumTagType and refIdTagType for structs and unions) should probably be moved to being productions on ExtType instead. This would mean that tagReferenceTypeExpr would have as its typerep extType(...) instead of tagType(...), which would be transformed back into extTypeExpr(...). This is a non-issue, as these would have the same pp, and actually would be a slight performance improvement since we would avoid looking up the refId when re-computing the typerep.

The TagType nonterminal, as far as I can tell, is only there to keep things better organized, so merging this with ExtType shouldn't break too many things, and the only major refactoring to do would be to replace all references to tagType with extType.

Overloading

Modifying overloading doesn't have to happen at the same time as these changes, but we do eventually want to be able to specify overloads on host types. We have a couple of options here:

  • Largely keep the current mechanism, and modify it such that an ExtType may specify a module name via an attribute. This would be less work, but more confusing in the long run. Also, with the addition of ExtTypes, being able to specify an overload on a struct type becomes redundant.
  • Return to a mechanism similar to what we had previously, utilizing dispatch productions, but non-interfering as I informally proved above. This method would be slightly more work now, but would be less confusing to new users of ableC, and could allow us to do away with some of the magic needed to make __attribute__((module(...))) work properly. This approach would also be a bit simpler than it was when first implemented, due to a few lessons learned since then.

@tedinski @ericvanwyk any thoughts?

Anonymous unions not supported.

Test case:

struct foo {
	enum {
		LEFT,
		RIGHT
	} disc;
	union {
		int i;
		float f;
	};
};

int main() {
	return 0;
}

Output on e44d98b:

Error at line 9, column 2 in file sad2.c
         (parser state: 296; real character index: 203):
  Expected a token of one of the following types:
   [edu:umn:cs:melt:ableC:concretesyntax:BlockComment,
    edu:umn:cs:melt:ableC:concretesyntax:Colon_t,
    edu:umn:cs:melt:ableC:concretesyntax:Identifier_t,
    edu:umn:cs:melt:ableC:concretesyntax:LParen_t,
    edu:umn:cs:melt:ableC:concretesyntax:LineComment,
    edu:umn:cs:melt:ableC:concretesyntax:NewLine_t,
    edu:umn:cs:melt:ableC:concretesyntax:Spaces_t,
    edu:umn:cs:melt:ableC:concretesyntax:Star_t,
    edu:umn:cs:melt:ableC:concretesyntax:cppTags:CPP_Location_Tag_t,
    edu:umn:cs:melt:ableC:concretesyntax:gcc_exts:PragmaMark]
   Input currently matches:
   [edu:umn:cs:melt:ableC:concretesyntax:Semi_t]

Incorrect handling of qualifiers for pointers in typeAssignableTo

This should be a subsetting relation, but right now we are checking that all qualifiers are identical. This means that something like

char *a;
const char *b = a;

is considered an error, while this should really be legal. As a temporary workaround in the feature/templating branch, I am disabling checking of qualifiers on pointers completely.

Jenkins takes >30 minutes to do downstream builds of all extensions

I'm about to get Silver building through a Jenkinsfile and integration testing with AbleC, and I find this length of time... annoying. A full Silver integration builds take 46 minutes. Yikes! We should reduce the ablec extensions' build time to less than 15. Ideally less than 5, but that might not be easy.

For the most part, this seems to be an issue with each extension for AbleC taking a rather long time. Even ablec-skeleton takes 6-7 minutes(!!) to run. I'm going to fix this. I'd like feedback on the plan. Do ya'll know what's making things take so long?

A plan:

  • I'm going to start working on #55, making extensions use a common "library" for their jenkins build behavior, so I can get things in better shape, and then easily get all the extensions working better.
  • Idea 1: I'm going to do the initial build with --warn-all --warn-error, and skip the MWDA and only do the MDA during the later step of modular analyses. This avoids one full rebuild in Jenkins.
  • Idea 2: I want to reduce the amount of re-building, so I may make sure the MDA can be run without needing the --clean flag.
  • Idea 3: I may add a parameter that tells the extension jenkinsfile how to get ablec's host build's generated files, so we can avoid re-building even that when ablec was just built.
  • Idea 4: I think the test makefile is rebuilding the extended jar? We should have it use the one already built...
  • Idea 5: A better approach to checking for a branch's existence than the exception approach we have right now.
  • I'm mildly annoyed by having to build so many different parsers in AbleC itself, but that may be unavoidable for now...? (Although... is decl separate from decls necessary? That would reduce the number by 20%!)
  • (I wish we could reduce the memory usage of silver builds, then we could increase executor count, but I don't know if there's any low hanging fruit there.)

Hi @krame505 @TravisCarlson do either of you have thoughts on what else might be taking so long or comments about the above ideas?

Scope handling for function decls is possibly wrong

In functionDecl, we are currently adding bty.defs both to the current scope for the body (via top.defs), as well as to the enclosing scope. I don't know if this is correct, but it seems wrong to be adding something to two different scopes for a new env.

Parameterized gcc Attributes are pretty-printed with erroneous parentheses

An attribute like __attribute__(name(arg1, arg2)) is currently being written by ableC as __attribute__((name(arg1,(arg2)))), but this is invalid syntax.

The specific example that brought this up was posix_memalign on osx in stdlib.h. Including this will raise this error (as in the matlab extension):

simple_cat.c:838:95: error: expected 'introduced', 'deprecated', or 'obsoleted'
signed int posix_memalign(void  * * , size_t  , size_t  ) __attribute__((availability(macosx, ((introduced) = 10.6))));

Removing the extra parentheses (after availability) will let gcc run the file.

Ideally we'd catch something like this in the future by adding in some tests that run on or simulate an osx environment.

This TODO: mentioned in VariableAttributes.sv looks like it could solve this bug.

Some generated builtins being ignored?

For example, all the __sync_fetch_and_... functions, which are provided by GCC, are indicated as 'ignored' by comments in GeneratedBuiltins.sv. The builtins generator is the one part of ableC that I haven't worked on in the past or been able to figure out on my own, @tedinski are you able to shed some light on what needs to be done here? I am asking because I am wanting to use these intrinsics in an actual project I am developing with ableC, and dealing with this has been kind of a pain.

BaseTypeExpr can contain TypeModiferExpr via directTypeExpr

I found this issue when working on #22, as there is no obvious solution for what directTypeExpr(ty) should forward to when ty.typeModiferExpr is not baseTypeExpr().

Currently, the issue shows up in situations like variableDecls, where there is a BaseTypeExpr and multiple TypeModiferExprs that are based on this type. The pp of directTypeExpr is just the pp of type that it wraps, but this means that if you have variableDecls with multiple Declarators and the BaseTypeExpr being directTypeExpr(pointerType(...)), then the * is printed before the Declarator list, so only the first one ends up being a pointer.

The fundamental issue here is that we shouldn't be able to have a TypeModifierExpr occur within a BaseTypeExpr in any way (at least in the host tree), so this is yet another reason why directTypeExpr really shouldn't be part of the host language. But since doing so is useful, we need to have some method of performing lifting of TypeModifierExprs to the top of BaseTypeExpr, then lowering and inserting them into the bottom of TypeModifierExpr to replace baseTypeExpr.

Here is my proposal to do that, which goes hand-in-hand with my other refactoring work to make directTypeExpr no longer part of the host:

  • Add a production typeModiferTypeExpr (BaseTypeExpr ::= BaseTypeExpr TypeModifierExpr). This is used for directTypeExpr(ty) to forward to when ty.typeModifierExpr is not baseTypeExpr()
  • Add synthesized and inherited attributes to lift a list of TypeModifierExprs from BaseTypeExpr and send them down the TypeModiferExpr tree. These must be provided from one to the other in every production that somehow wraps a BaseTypeExpr and one or more TypeModifierExprs (e.g. typeName, variableDecls, some extensions, etc.)
  • Define the host attribute on typeModiferTypeExpr to be its parameter BaseTypeExpr
  • Define the host attribute on baseTypeExpr to be the new tree constructed from the parameter TypeModiferExprs

Since these changes also involve some further refactoring of the lifting stuff, I will be committing this in the feature/template branch, and will push once #21 is merged.

Extensions using Jenkins library

Right now we have duplicated Jenkinsfiles in every extension. This makes it difficult to fix up the build & test process for each extension all at once.

Jenkins pipelines support "shared libraries" : https://jenkins.io/doc/book/pipeline/shared-libraries/

If I understand this documentation correctly, we could do this:

Create a melt-jenkins repo, with the organization suggested in that link (probably just using the vars/ approach).

Then we should be able to import that library by writing:

@Library('github.com/melt-umn/melt-jenkins@master') _

Inside each extension. I suspect we should then have each extension have a Jenkinsfile that looks like this:

@Library('github.com/melt-umn/melt-jenkins@master') _

properties(ablecExtensionDefaultProperties)

buildAbleCExtension("ableC-condition-tables")

I expect our library would have:

  • Some default values: ablecExtensionDefaultProperties and silverDefaultProperties for ableC extensions and Silver projects generally. So we don't have to repeat their descriptions and the like.
  • buildAbleCExtension written all in one place
  • notifyBuild doesn't need repeating everywhere
  • Maybe other helpers / refactoring as needed. :) I'd like to use some of these things in refactoring the AbleC Jenkinsfile itself, and as part of writing a Jenkinsfile for Silver (finally) too.

Thoughts?

Merge returnType into env

Right now we have 2 inherited attributes that get passed around to basicly everything: env and returnType. env contains all the info about the current context of a piece of code, except for the return type, which is annoying. returnType could become part of the env by adding a new namespace on Env.
This wouldn't actually need to be a full-fledged namespace list of Scopes, just a new attribute that would return whatever the innermost return type is, or nothing.

'with_all' doesn't build successfully

This is quite nice when trying to test changes, and is something we'll want Jenkins to be building once we get this going again with Jenkins...

Errors for : artifact :
Main.sv:12:2: error: Grammar 'edu:umn:cs:melt:exts:ableC:gc' cannot be found.


Errors for : edu:umn:cs:melt:exts:ableC:adt:abstractsyntax :
DataType.sv:372:6: error: Attribute 'position' does not occur on 'edu:umn:cs:melt:ableC:abstractsyntax:TypeNames'. Looked at:
	edu:umn:cs:melt:exts:ableC:adt:abstractsyntax:position (Match.sv:194)

DataType.sv:373:6: error: Undeclared attribute 'name_i'.
DataType.sv:389:14: error: Undeclared attribute 'asStructItemList'.
DataType.sv:406:14: error: Undeclared attribute 'asParameters'.
DataType.sv:470:14: error: Undeclared attribute 'asAssignments'.

Refactor/expand binaryOpExpr and unaryOpExpr

Currently we have a single binaryOpExpr production in Expr.sv with children lhs::Expr op::BinOp rhs::Expr, and many productions for the binary operators in ExprBinOps.sv, which then have inherited attributes op.lop = lhs; op.rop = rhs;.

In the type qualifiers paper, we wanted to explain an operator overloading example as simply as possible. The feature/type_qualifiers branch replaces the use of addOp with an addExpr production that has children lhs::Expr rhs::Expr. The ableC paper similarly uses a unaryMinusDispatch production with child e::Expr rather than unaryOpExpr(negativeOp()).

Using binaryOpExpr reduces the lines of code needed. Alternatively, addExpr/subtractExpr/etc. productions would need to be created in Expr.sv and overload/Expr.sv, which are longer than the addOp/subOp/etc. productions currently in ExprBinOps.sv and overload/ExprBinOps.sv. But, if this is easier to understand, might it be worth it?

I'm creating this issue to gauge opinion before deciding what to do next on the type qualifiers branch: either revert the new addExpr/etc. productions back to addOp, or convert more of the Op productions to Expr productions.

Jenkins fails to mkdir first time

The feature/jenkins and fix/mwda-special-specifiers branches of ableC failed to build today. The logs showed the generated/ directory did not exist even after running sh "mkdir -p generated". But the builds succeeded after simply running a second time.

Label defs and env should not be tied to the main env

I get the following error when attempting to forward to a labelStmt.

error: INTERNAL compiler error: expected to find label in function scope, was missing.

The remaining use of txtStmt in the Cilk extension is related to this. Though I've also tried on a simpler extension and found the same error.

https://github.com/melt-umn/ableC-cilk/blob/develop/grammars/edu.umn.cs.melt.exts.ableC.cilk/abstractsyntax/Sync.sv#L103

txtStmt("_cilk_sync" ++ toString(syncCount) ++ ":;")
-- TODO: replace txtStmt with labelStmt
-- labelStmt(name("_cilk_sync" ++ toString(syncCount), location=builtinLoc(MODULE_NAME)), nullStmt())

ADT extension requires manual recursive freeing

For all recursive ADTs, it is necessary to write a tedious and standard recursive freeing function. This seems like code that could be generated.

Alternatively, and even better, this could be implemented to use the Boehm-Demers-Weiser garbage collector, so deallocation would be automatic. I have been thinking of doing this as a separate extension that could get used by other extensions, as the library has a bunch of macro calls.

Using garbage collection would probably be the best option, as I plan to build off this extension to add rewriting, etc. and manual freeing would get rather complex and hard to manage.

Delete `edu:umn:cs:melt:ableC:hosts` grammar

We have both a top-level edu:umn:cs:melt:ableC:host grammar with the default composition, and also edu:umn:cs:melt:ableC:hosts:default which seems to be the same thing? One of these should be removed, probably.

Looking up an overload from outside the overloaded production is painful

Right now we have the collection attributes for everything inside productions. This means that we run into issues if we want to, for example, look up whether show is overloaded for a subtype when computing a different overload.

This could be fixed by moving these collection attributes to overload lookup functions, and writing aspect functions instead of aspect productions to specify overloads in extensions.

mergeQualifiers should be parameterized by a corresponding inherited attribute

Currently mergeQualifiers<a> has type (a ::= a). Instead should have type a, and there should be a corresponding inherited attribute mergeQualifiersWith<a>::a (or whatever you want to call it) that is used as the 'parameter' to this analysis instead. This is mainly a stylistic thing for consistency, since right now it doesn't really jive with how we do this sort of transformation in attribute grammars, but also in order to make things considerably less weird for extensions, if they want to override this equation on a forwarding Type (in a non-interfering way, of course - one may simply want to 'do the best job possible' in preserving their custom type, in order to maintain pp, etc.)

Label defs should be propagated from inside stmtExpr

Currently we only propagate label defs across statements. However, labels may occur inside statements inside expressions inside statements, and should be visible at the top level of statements.

Note that goto isn't allowed to such labels directly, but computed goto (which we don't support at all right now...) should be allowed, so we will need to introduce some method of distinguishing whether a label in the environment is nested inside the environment or not.
For example, this should not be allowed:

int main(void) 
{   
    ({l1: ; 0;});
    goto l1;
    return 0;
}

but this should:

int main(void) 
{   
    ({l1: ; 0;});
    void *ptr = &&l1;
    goto *ptr;
    return 0;
}

This is a seperate issue from #77, although that redesign should probably happen first.

Use sv-nailgun for expected-results tests

I'm not sure why, but we seem to just be re-invoking the jar for each test, which is considerably slower. Since this is the script that gets run by Jenkins, is there any reason why this is not using sv-nailgun?

Special specifiers on function prototypes are discarded

For example

inline int foo(int);

translates into

signed int foo(signed int  );

discarding the inline special specifier. As far as I can tell the abstract syntax has no way of representing special specifiers on function prototypes? Not really sure of the best way to fix this.

Ambiguous '('

It seems that ableC doesn't build due the ambiguity of '(' - the first error I get is

Declarations.sv:64:21: error: Found ambiguous possibilities for '('
	edu:umn:cs:melt:ableC:concretesyntax:c11:C11_Atomic_LParen_t (C11.sv:100)
	edu:umn:cs:melt:ableC:concretesyntax:LParen_t (Terminals.sv:218)

I saw an email where @200sc mentioned this, but I can't find it now and I don't see this as an issue anywhere.

Missing constant analysis

In some cases where a constant is required, ableC will allow non-constants. For example:

int f() {
  return 4;
}

int x = f();

is accepted and translated by ableC, but it does not compile with gcc.

Move source grammar to a `grammars` directory

This would make things consistent with just about every other major Silver project, AFAIK. Changing this will be annoying and break things, but waiting will make the problem worse...

Also, I soon will want to be introducing a new grammar for the silver-ableC extension, which probably belongs under edu.umn.cs.melt.exts.silver.ableC and not part of the host language grammars - it would be good not to have these both sitting at the top level of the repo. IDK, maybe the builtins processor grammar could move there, too.

This is something I want to fix soon-ish, before diving into the implementation of the silver-ableC extension... so, thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.