Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,21 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
}
}

void visit_ClassDef(const AST::ClassDef_t &x) {
SymbolTable *parent_scope = current_scope;
current_scope = al.make_new<SymbolTable>(parent_scope);
for (size_t i=0; i<x.n_body; i++) {
visit_stmt(*x.m_body[i]);
}
tmp = ASR::make_ClassType_t(al, x.base.base.loc, current_scope,
x.m_name, ASR::abiType::Source, ASR::accessType::Public);
tmp = ASR::make_Class_t(al, x.base.base.loc,
ASR::down_cast<ASR::symbol_t>(tmp), nullptr, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Class ASR node is used for a variable type, so in here we should just remove it.

ASR::symbol_t * t = ASR::down_cast<ASR::symbol_t>(tmp);
parent_scope->scope[x.m_name] = t;
Comment on lines +1496 to +1501
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@certik Does this look good?

On Python code:

class Foo:
    def __init__(self, p):
        return p

ASR:

Internal Compiler Error: Unhandled exception
Traceback (most recent call last):
  File "/Users/thebigbool/repos/lpython/src/bin/lpython.cpp", line 755
    return emit_asr(arg_file, runtime_library_dir,
  File "/Users/thebigbool/repos/lpython/src/bin/lpython.cpp", line 169
    std::cerr << diagnostics.render(input, lm, compiler_options);
  File "/Users/thebigbool/repos/lpython/src/libasr/diagnostics.cpp", line 71
    out += render_diagnostic(d, input, lm,
  File "/Users/thebigbool/repos/lpython/src/libasr/diagnostics.cpp", line 134
    populate_spans(d, lm, input);
  File "/Users/thebigbool/repos/lpython/src/libasr/diagnostics.cpp", line 121
    populate_span(s, lm, input);
  File "/Users/thebigbool/repos/lpython/src/libasr/diagnostics.cpp", line 113
    LFORTRAN_ASSERT(s.source_code.size() > 0)
AssertFailed: s.source_code.size() > 0

Also, what is the difference between Class and ClassProcedure Nodes in ASR?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a bug in printing an error message, I just created an issue #398 to fix that.

Yes, I think that is a constructor. Fortran does not have constructors in this sense, so I would tackle those a little bit later. We should add whatever we need into ASR, but first let's get something like this working:

class Foo:
    def __init__(self: Foo, a: i32, b: i32, c: i32):
        self.a: i32 = a
        self.b: i32 = b
        self.c: i32 = c

    def get_a(self: Foo) -> i32:
        return self.a

I am not quite sure where you should annotate the variables inside the class, whether how I did it, or some other way.

The other thing we need are structs, which we can represent already in ASR, we just need some syntax in Python, possibly the "data classes" or whatever it is called:

@dataclass # or whatever it is called
class MyStruct:
    a: i32
    b: f64
    c: str

And it works like a struct.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To annotate that a is an instance of the class Foo, we can do:

a: Foo
a = Foo()

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not quite sure where you should annotate the variables inside the class, whether how I did it, or some other way.

The way you did it seems fine.

current_scope = parent_scope;
}

void create_GenericProcedure(const Location &loc) {
for(auto &p: overload_defs) {
std::string def_name = p.first;
Expand Down