Skip to content

Commit

Permalink
add language extensions: SAFE and UNSAFE (#372)
Browse files Browse the repository at this point in the history
* add language extensions: SAFE and UNSAFE
* add Safe Mode option to hi

Co-authored-by: dawa79 <Dan.Wang2@morganstanley.com>
  • Loading branch information
smunix and dawa79 committed Sep 28, 2020
1 parent 8388899 commit 47df59d
Show file tree
Hide file tree
Showing 37 changed files with 11,918 additions and 10,468 deletions.
10 changes: 9 additions & 1 deletion bin/hi/evaluator.C
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,9 @@ void printQualType(const hobbes::Constraints& cs, const hobbes::MonoTypePtr& ty)
}

void evaluator::printTypeOf(const std::string& expr, bool showHiddenTCs) {
hobbes::QualTypePtr t = this->ctx.unsweetenExpression(readExpr(expr))->type();
hobbes::QualTypePtr t = this->ctx.unsweetenExpression(hobbes::translateExprWithOpts(this->opts,
this->ctx.readExpr(expr),
[](std::string const&) -> void {}))->type();
hobbes::Constraints cs = showHiddenTCs ? t->constraints() : hobbes::expandHiddenTCs(this->ctx.typeEnv(), t->constraints());
hobbes::QualTypePtr st = hobbes::simplifyVarNames(hobbes::qualtype(cs, t->monoType()));

Expand All @@ -180,6 +182,12 @@ void evaluator::printTypeOf(const std::string& expr, bool showHiddenTCs) {

void evaluator::printTypeEnv() {
std::cout << setfgc(colors.typefg);
if (std::find(opts.begin(), opts.end(), "Safe") != std::end(opts)) {
this->ctx.dumpTypeEnv([this](std::string const& binding) -> std::string const& {
return hobbes::SafeSet::get(binding);
});
return;
}
this->ctx.dumpTypeEnv();
}

Expand Down
1 change: 1 addition & 0 deletions bin/hi/evaluator.H
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct Args {
strs opts;

Args() : useDefColors(false), silent(false), replPort(-1), httpdPort(-1), exitAfterEval(false), machineREPL(false) {
opts.push_back("Safe");
}
};

Expand Down
23 changes: 20 additions & 3 deletions bin/hi/main.C
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <hobbes/util/array.H>
#include <hobbes/util/str.H>
#include <hobbes/util/os.H>
#include <hobbes/eval/cmodule.H>

#include <iostream>
#include <fstream>
Expand Down Expand Up @@ -178,7 +179,15 @@ void showShellHelp() {
{":o K", "Enable language option K"},
{":^", "Echo back the command history"},
{":r", "Start printing debug traces as type constraints are refined"},
{":nr", "Stop printing debug traces as type constraints are refined"}
{":nr", "Stop printing debug traces as type constraints are refined"},
{":showUnsafe", "show unsafe functions"}
});
}

void showUnsafeSymbols() {
hobbes::SafeSet::forEach([](std::string const&, hobbes::SafeSet::Status const& status, std::string const& desc) {
if (hobbes::SafeSet::Status::UnSafe == status)
std::cout << desc << std::endl;
});
}

Expand Down Expand Up @@ -322,7 +331,10 @@ void evalLine(char* x) {
eval->showConstraintRefinement(false);
std::cout << "Type constraint refinement debugging OFF" << std::endl;
return;
}
} else if (line == ":showUnsafe") {
showUnsafeSymbols();
return;
}

if (line.size() > 2) {
std::string cmd = line.substr(0, 2);
Expand Down Expand Up @@ -641,7 +653,12 @@ Args processCommandLine(int argc, char** argv) {
break;
}
case 5:
r.opts.push_back(arg);
if (0 == arg.rfind("no-", 0)) {
r.opts.erase(std::remove(r.opts.begin(), r.opts.end(), arg.substr(3)), r.opts.end());
}
else {
r.opts.push_back(arg);
}
m = 0;
break;
}
Expand Down
14,809 changes: 7,688 additions & 7,121 deletions include/hobbes/boot/gen/bootdata.H

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions include/hobbes/eval/cc.H
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ public:
llvm::Module* module() const;

// dump the contents of the active type environment (useful for debugging)
void dumpTypeEnv() const;
void dumpTypeEnv(str::seq* syms, str::seq* types) const;
std::string showTypeEnv() const;
void dumpTypeEnv(std::function<std::string const&(std::string const&)> const& = [](std::string const& binding) -> std::string const& { return binding; }) const;
void dumpTypeEnv(str::seq* syms, str::seq* types, std::function<std::string const&(std::string const&)> const& = [](std::string const& binding) -> std::string const& { return binding; }) const;
std::string showTypeEnv(std::function<std::string const&(std::string const&)> const& = [](std::string const& binding) -> std::string const& { return binding; }) const;

const TEnvPtr& typeEnv() const;

Expand Down
27 changes: 26 additions & 1 deletion include/hobbes/eval/cmodule.H
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,32 @@ typedef std::map<std::string, std::string> OptDescs;
OptDescs getAllOptions();

ExprPtr translateExprWithOpts(const ModulePtr&, const ExprPtr&);
ExprPtr translateExprWithOpts(const std::vector<std::string>&, const ExprPtr&);
ExprPtr translateExprWithOpts(const std::vector<std::string>&, const ExprPtr&, std::function<void(std::string const&)> const& = [](std::string const& err) -> void { throw std::runtime_error(err); });

// change set of safe/unsafe expressions allowed in Safe mode
class SafeSet {
public:
enum class Status {
UnSafe = 1,
Safe = 2,
Undefined
};
friend std::ostream& operator<<(std::ostream& os, const Status& s) {
if (s == Status::UnSafe) {
os << "UnSafe";
} else if(s == Status::Safe) {
os << "Safe";
} else {
os << "Undefined";
}
return os;
}

static std::string const& get(std::string const& /*binding*/);
static void setUnsafeFn(std::string const& /*var*/);
static void setSafeFn(std::string const& /*var*/);
static void forEach(std::function<void (std::string const& /*var*/, Status const& /*status*/, std::string const& /*desc*/)> const&);
};

}

Expand Down
33 changes: 33 additions & 0 deletions include/hobbes/lang/module.H
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,30 @@ private:
typedef std::shared_ptr<InstanceDef> InstanceDefPtr;
typedef std::vector<InstanceDefPtr> InstanceDefs;

class MUnsafePragmaDef : public ModuleDefCase<MUnsafePragmaDef> {
public:
MUnsafePragmaDef(const std::string& symbol, const LexicalAnnotation& la) : Base(la), symbol(symbol) {}
void show(std::ostream& out) const { out << "{-# UNSAFE " << symbol << " #-}"; } ;

const std::string& symbolValue() const { return symbol; }
static const int type_case_id = 6;

private:
std::string symbol;
};

class MSafePragmaDef : public ModuleDefCase<MSafePragmaDef> {
public:
MSafePragmaDef(const std::string& symbol, const LexicalAnnotation& la) : Base(la), symbol(symbol) {}
void show(std::ostream& out) const { out << "{-# SAFE " << symbol << " #-}"; } ;

const std::string& symbolValue() const { return symbol; }
static const int type_case_id = 7;

private:
std::string symbol;
};

template <typename Case>
ModuleDefCase<Case>::ModuleDefCase(const LexicalAnnotation& la) : ModuleDef(Case::type_case_id, la) {
}
Expand All @@ -164,6 +188,8 @@ template <typename T>
virtual T with(const MVarDef*) const = 0;
virtual T with(const ClassDef*) const = 0;
virtual T with(const InstanceDef*) const = 0;
virtual T with(const MUnsafePragmaDef*) const = 0;
virtual T with(const MSafePragmaDef*) const = 0;
};

template <typename T>
Expand All @@ -181,6 +207,10 @@ template <typename T>
return f.with(reinterpret_cast<const ClassDef*>(p.get()));
case InstanceDef::type_case_id:
return f.with(reinterpret_cast<const InstanceDef*>(p.get()));
case MUnsafePragmaDef::type_case_id:
return f.with(reinterpret_cast<const MUnsafePragmaDef*>(p.get()));
case MSafePragmaDef::type_case_id:
return f.with(reinterpret_cast<const MSafePragmaDef*>(p.get()));
default:
{
std::ostringstream ss;
Expand All @@ -200,6 +230,9 @@ struct switchMDefTyFn : switchMDef<ModuleDefPtr> {
ModuleDefPtr with(const MVarDef*) const;
ModuleDefPtr with(const ClassDef*) const;
ModuleDefPtr with(const InstanceDef*) const;
ModuleDefPtr with(const MUnsafePragmaDef*) const;
ModuleDefPtr with(const MSafePragmaDef*) const;

};

// a module is a collection of module definitions
Expand Down
2 changes: 1 addition & 1 deletion include/hobbes/lang/type.H
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public:
// get access to the internal type environment map (should only be used for debugging)
typedef std::map<std::string, PolyTypePtr> PolyTypeEnv;

PolyTypeEnv typeEnvTable() const;
PolyTypeEnv typeEnvTable(std::function<std::string const&(std::string const&)> const& = [](std::string const& binding) -> std::string const& { return binding; }) const;
str::set boundVariables() const;

typedef std::map<std::string, UnqualifierPtr> Unqualifiers;
Expand Down

0 comments on commit 47df59d

Please sign in to comment.