Skip to content
This repository has been archived by the owner on Nov 24, 2024. It is now read-only.

Commit

Permalink
inline assebmly
Browse files Browse the repository at this point in the history
  • Loading branch information
SaptakBhoumik committed Mar 14, 2022
1 parent a106da9 commit b687b38
Show file tree
Hide file tree
Showing 14 changed files with 145 additions and 8 deletions.
24 changes: 24 additions & 0 deletions Peregrine/ast/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1807,4 +1807,28 @@ AstKind PrivateDef::type() const { return KAstPrivate; }
std::string PrivateDef::stringify() const {
return"private " + m_definition->stringify();
}
InlineAsm::InlineAsm(Token token,std::string assembly,AstNodePtr output,std::vector<std::pair<std::string,AstNodePtr>>inputs){
m_token=token;
m_assembly=assembly;
m_output=output;
m_inputs=inputs;
}
std::string InlineAsm::assembly() const{return m_assembly;}
AstNodePtr InlineAsm::output() const{return m_output;}
std::vector<std::pair<std::string,AstNodePtr>> InlineAsm::inputs() const{return m_inputs;}
Token InlineAsm::token() const { return m_token; }
AstKind InlineAsm::type() const { return KAstInlineAsm; }
std::string InlineAsm::stringify() const{
std::string res ="__asm__:\n";
if(m_output->type()==KAstNoLiteral){
res+=" "+m_assembly+"\n";
}
else{
res+=" "+m_output->stringify()+" = "+m_assembly+"\n";
}
for(size_t i=0;i<m_inputs.size();++i){
res+=" "+m_inputs[i].first+" = "+m_inputs[i].second->stringify()+"\n";
}
return res;
}
} // namespace ast
18 changes: 17 additions & 1 deletion Peregrine/ast/ast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ enum AstKind {
KAstExternFuncDef,
KAstExternStruct,
KAstCompileTimeExpression,
KAstPrivate
KAstPrivate,
KAstInlineAsm
};

class AstVisitor;
Expand Down Expand Up @@ -1275,6 +1276,21 @@ class PrivateDef: public AstNode {
std::string stringify() const;
void accept(AstVisitor& visitor) const;
};
class InlineAsm: public AstNode {
Token m_token;
std::string m_assembly;
AstNodePtr m_output;
std::vector<std::pair<std::string,AstNodePtr>> m_inputs;
public:
InlineAsm(Token token,std::string assembly,AstNodePtr output,std::vector<std::pair<std::string,AstNodePtr>>inputs);
std::string assembly() const;
AstNodePtr output() const;
std::vector<std::pair<std::string,AstNodePtr>> inputs() const;
Token token() const;
AstKind type() const;
std::string stringify() const;
void accept(AstVisitor& visitor) const;
};
} // namespace ast

#endif
1 change: 1 addition & 0 deletions Peregrine/ast/visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,5 @@ void EllipsesTypeExpr::accept(AstVisitor &visitor) const {visitor.visit(*this);}
void CompileTimeExpression::accept(AstVisitor &visitor) const {visitor.visit(*this);}
void TernaryFor::accept(AstVisitor &visitor) const {visitor.visit(*this);}
void PrivateDef::accept(AstVisitor &visitor) const {visitor.visit(*this);}
void InlineAsm::accept(AstVisitor &visitor) const {visitor.visit(*this);}
} // namespace ast
1 change: 1 addition & 0 deletions Peregrine/ast/visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class AstVisitor {
virtual bool visit(const CompileTimeExpression& node) { return false; };
virtual bool visit(const TernaryFor& node) { return false; };
virtual bool visit(const PrivateDef& node) { return false; };
virtual bool visit(const InlineAsm& node) { return false; };

};

Expand Down
26 changes: 25 additions & 1 deletion Peregrine/codegen/cpp/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1262,5 +1262,29 @@ bool Codegen::visit(const ast::PrivateDef& node){
node.definition()->accept(*this);
return true;
}

bool Codegen::visit(const ast::InlineAsm& node){
write("__asm__(\""+node.assembly()+"\"\n");
if(node.output()->type()!=ast::KAstNoLiteral){
write(": \"=r\" (");
node.output()->accept(*this);
write(")\n");
}
auto in=node.inputs();
if(in.size()!=0){
write(": ");
}
for(size_t i=0;i<in.size();i++){
auto x=in[i];
write("\"");
write(x.first);
write("\" (");
x.second->accept(*this);
write(")\n");
if(i<in.size()-1){
write(",");
}
}
write(")");
return true;
}
} // namespace cpp
3 changes: 2 additions & 1 deletion Peregrine/codegen/cpp/codegen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ class Codegen : public ast::AstVisitor {
bool visit(const ast::ExternStructLiteral& node);
bool visit(const ast::ExternUnionLiteral& node);
bool visit(const ast::ExternFuncDef& node);
bool visit(const ast::PrivateDef&);
bool visit(const ast::PrivateDef& node);
bool visit(const ast::InlineAsm& node);
EnvPtr m_env;
};

Expand Down
2 changes: 2 additions & 0 deletions Peregrine/lexer/lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ static inline TokenType token_type(std::string item, std::string next_item) {
return tk_export;
}else if (item == "private") {
return tk_private;
}else if (item == "__asm__") {
return tk_asm;
}else {
return is_number(item);
}
Expand Down
3 changes: 2 additions & 1 deletion Peregrine/lexer/lexer_re.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ void LEXER::add_unknown(){
{"inline",tk_inline},
{"virtual",tk_virtual},
{"class",tk_class},
{"export",tk_export}
{"export",tk_export},
{"__asm__",tk_asm}
};
if(m_keyword=="f" && (m_curr_item=='"'||m_curr_item=='\'')){
type=tk_format;
Expand Down
1 change: 1 addition & 0 deletions Peregrine/lexer/tokens.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ enum TokenType {
tk_identifier, // foo, bar

// keywords tokens
tk_asm, // __asm__
tk_private, // private
tk_static, // static
tk_scope, // scope
Expand Down
48 changes: 48 additions & 0 deletions Peregrine/parser/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ AstNodePtr Parser::parseStatement() {
stmt = parseTypeDef();
break;
}
case tk_asm: {
stmt = parseAsm();
break;
}

case tk_class: {
stmt = parseClassDefinition();
Expand Down Expand Up @@ -2070,4 +2074,48 @@ AstNodePtr Parser::parsePrivate(bool is_class){
}
}
return std::make_shared<PrivateDef>(tok,exp);
}
AstNodePtr Parser::parseAsm(){
auto tok=m_currentToken;
expect(tk_colon,"Expected an ':' but got "+next().keyword+" instead","","","");
expect(tk_ident,"Expected an indentation but got "+next().keyword+" instead","","","");
advance();
std::string assembly="";
AstNodePtr output=std::make_shared<NoLiteral>();
std::vector<std::pair<std::string,AstNodePtr>> inputs;
while(m_currentToken.tkType!=tk_dedent){
if(m_currentToken.tkType==tk_identifier){
output=parseExpression();
expect(tk_assign,"Expected an '=' but got "+next().keyword+" instead","","","");
advance();
if(assembly.size()!=0){
error(m_currentToken,"Error: Can't have multiple result variable","","","");
}
else{
assembly=m_currentToken.keyword;
}
}
else if(m_currentToken.tkType==tk_string){
if(assembly.size()!=0 && next().tkType!=tk_assign){
error(m_currentToken,"Error: Can't have multiple result variable","","","");
}
else if(next().tkType==tk_assign){
auto reg=m_currentToken.keyword;
advance();
advance();
auto exp=parseExpression();
inputs.push_back(std::make_pair(reg,exp));
}
else{
assembly=m_currentToken.keyword;
}
}
else{
error(m_currentToken,"Expected an identifier or string but got "+m_currentToken.keyword+" instead","","","");
}
advance();
if(m_currentToken.tkType==tk_dedent){break;}
if(m_currentToken.tkType==tk_new_line){advance();}
}
return std::make_shared<InlineAsm>(tok,assembly,output,inputs);
}
1 change: 1 addition & 0 deletions Peregrine/parser/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class Parser {
AstNodePtr parseExtern();
AstNodePtr parseMultipleAssign(AstNodePtr);
AstNodePtr parseVirtual();
AstNodePtr parseAsm();
AstNodePtr parseCast();
AstNodePtr parseStatement();
AstNodePtr parseWith();
Expand Down
2 changes: 1 addition & 1 deletion Peregrine/parser/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Token Parser::next() {
}

PrecedenceType Parser::nextPrecedence() {
if(m_currentToken.tkType == tk_new_line) {
if(m_currentToken.tkType == tk_new_line||m_currentToken.tkType == tk_dedent) {
return pr_lowest;
}
else if (precedenceMap.count(next().tkType) > 0) {
Expand Down
8 changes: 7 additions & 1 deletion Peregrine/test.pe
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,10 @@ class x:
private static x=2
private static const x=2
private static def (i:int)method(a:int,b:int):
return a+b
return a+b
__asm__:
";your assambly code here"
"0"=reg_value
__asm__:
res=";your assambly code here"
"0"=reg_value
15 changes: 13 additions & 2 deletions can_comp.pe
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ def peregrine3()->int,int:
def peregrine2()->int,int:
return 3,3
return 4,4
class x.x
"class x.x
class x.x:
xx:int
union x.y
union x.y:
xx:int
def x.b(int,...)->int
def x.b(int,...)->int"
def unknown_type(var):
var.__add__(1)
for x in var:
Expand Down Expand Up @@ -184,7 +184,18 @@ def (const y:int)multiply2(const x:int)->int:
return x*y
private def private_func():
printf("Hello from private function\n")

def inline_asm():
arg1:int=45
arg2:int=50
add:int=0
__asm__:
add="addl %%ebx,%%eax"
"a"=arg1
"b"=arg2
printf("%lld + %lld = %lld\n",arg1,arg2,add)
def main():
inline_asm()
private_func()
switch:iterate_test=iterate_test(5)
switch2:int=switch.__add__(test(5))
Expand Down

0 comments on commit b687b38

Please sign in to comment.