Skip to content

Commit f905413

Browse files
authored
Compile function args. (#36)
* Pass build. * Clean up. * Compile function args. Co-authored-by: Bowen Fu <missing>
1 parent cafca59 commit f905413

File tree

5 files changed

+73
-67
lines changed

5 files changed

+73
-67
lines changed

include/lisp/compiler.h

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,15 @@
55
#include "evaluator.h"
66
#include <optional>
77

8+
enum class Scope
9+
{
10+
kLOCAL,
11+
kGLOBAL
12+
};
13+
814
class Compiler
915
{
10-
using SymbolTable = std::map<std::string, std::pair<ExprPtr, size_t>>;
16+
using SymbolTable = std::map<std::string, size_t>;
1117
SymbolTable mSymbolTable{};
1218
ByteCode mCode{};
1319
using FuncInfo = std::pair<Instructions, SymbolTable>;
@@ -16,14 +22,28 @@ class Compiler
1622
{
1723
return mFunc ? mFunc.value().first : mCode.instructions;
1824
}
19-
// auto& resolveIndex(std::string const& name) const
20-
// {
21-
// return mFunc ? mFuncInstructions.value() : mCode.instructions;
22-
// }
23-
// auto& define(std::string const& name)
24-
// {
25-
// return mFunc ? mFuncInstructions.value() : mCode.instructions;
26-
// }
25+
std::pair<size_t, Scope> getIndex(std::string const& name) const
26+
{
27+
if (mFunc)
28+
{
29+
auto const map = mFunc.value().second;
30+
auto iter = map.find(name);
31+
if (iter != map.end())
32+
{
33+
return {iter->second, Scope::kLOCAL};
34+
}
35+
}
36+
auto const idx = mSymbolTable.at(name);
37+
return {idx, Scope::kGLOBAL};
38+
}
39+
std::pair<size_t, Scope> define(std::string const& name)
40+
{
41+
auto& map = mFunc ? mFunc.value().second : mSymbolTable;
42+
auto const idx = map.size();
43+
map[name] = idx;
44+
auto const scope = mFunc ? Scope::kLOCAL : Scope::kGLOBAL;
45+
return {idx, scope};
46+
}
2747
public:
2848
Compiler() = default;
2949
void compile(ExprPtr const& expr);

include/lisp/evaluator.h

Lines changed: 29 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class Env;
2020
class Variable;
2121

2222
// bool : variadic
23-
using Params = std::variant<std::string, std::pair<std::vector<std::string>, bool>>;
23+
using Params = std::pair<std::vector<std::string>, bool>;
2424

2525
template <typename Iter>
2626
ExprPtr reverseVecToCons(Iter begin, Iter end);
@@ -90,38 +90,29 @@ class Env
9090
std::shared_ptr<Env> extend(Params const& parameters, std::vector<ExprPtr> const& arguments)
9191
{
9292
std::map<std::string, ExprPtr> frame;
93-
if (auto s = std::get_if<std::string>(&parameters))
93+
auto const& params = parameters.first;
94+
auto const variadic = parameters.second;
95+
if (variadic)
9496
{
95-
frame.insert({*s, reverseVecToCons(arguments.rbegin(), arguments.rend())});
97+
ASSERT(params.size() <= arguments.size() + 1);
9698
}
9799
else
98100
{
99-
auto paramsAndVariadic = std::get_if<1>(&parameters);
100-
ASSERT(paramsAndVariadic);
101-
auto const& params = paramsAndVariadic->first;
102-
auto const variadic = paramsAndVariadic->second;
103-
if (variadic)
101+
ASSERT(params.size() == arguments.size());
102+
}
103+
if (!params.empty())
104+
{
105+
for (size_t i = 0; i < params.size() - 1; ++i)
104106
{
105-
ASSERT(params.size() <= arguments.size());
107+
frame.insert({params.at(i), arguments.at(i)});
106108
}
107-
else
109+
if (variadic)
108110
{
109-
ASSERT(params.size() == arguments.size());
111+
frame.insert({params.back(), reverseVecToCons(arguments.rbegin(), arguments.rend() - static_cast<long>(params.size()) + 1)});
110112
}
111-
if (!params.empty())
113+
else
112114
{
113-
for (size_t i = 0; i < params.size() - 1; ++i)
114-
{
115-
frame.insert({params.at(i), arguments.at(i)});
116-
}
117-
if (variadic)
118-
{
119-
frame.insert({params.back(), reverseVecToCons(arguments.rbegin(), arguments.rend() - static_cast<long>(params.size()) + 1)});
120-
}
121-
else
122-
{
123-
frame.insert({params.back(), arguments.back()});
124-
}
115+
frame.insert({params.back(), arguments.back()});
125116
}
126117
}
127118

@@ -575,32 +566,23 @@ class CompoundProcedureBase : public Procedure, public std::enable_shared_from_t
575566
{
576567
std::ostringstream o;
577568
o << getClassName() << " (";
578-
if (auto s = std::get_if<std::string>(&mArguments))
579-
{
580-
o << ". " << *s << ", ";
581-
}
582-
else
569+
auto const& params = mArguments.first;
570+
auto const variadic = mArguments.second;
571+
if (!params.empty())
583572
{
584-
auto paramsAndVariadic = std::get_if<1>(&mArguments);
585-
ASSERT(paramsAndVariadic);
586-
auto const& params = paramsAndVariadic->first;
587-
auto const variadic = paramsAndVariadic->second;
588-
if (!params.empty())
573+
for (auto i = params.begin(); i != std::prev(params.end()); ++i)
574+
{
575+
o << *i << " ";
576+
}
577+
if (variadic)
578+
{
579+
o << ". ";
580+
}
581+
if (params.size() >= 1)
589582
{
590-
for (auto i = params.begin(); i != std::prev(params.end()); ++i)
591-
{
592-
o << *i << " ";
593-
}
594-
if (variadic)
595-
{
596-
o << ". ";
597-
}
598-
if (params.size() >= 1)
599-
{
600-
o << params.back();
601-
}
602-
o << ", ";
583+
o << params.back();
603584
}
585+
o << ", ";
604586
}
605587
o << mBody->toString() << ", ";
606588
o << "<procedure-env>)";

include/lisp/parser.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ inline Params parseParams(ExprPtr const& expr)
4545
auto me = expr;
4646
if (auto e = dynamic_cast<RawWord*>(me.get()))
4747
{
48-
return e->get();
48+
params.push_back(e->get());
49+
return std::make_pair(params, true);
4950
}
5051
while (me != nil())
5152
{

src/compiler.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ void Compiler::compile(ExprPtr const& expr)
5858
{
5959
funcSymPtr->setName(defPtr->mVariableName);
6060
}
61-
instructions().push_back(kSET_GLOBAL);
62-
auto index = mSymbolTable.size();
63-
mSymbolTable.insert({defPtr->mVariableName, {defPtr->mValue, index}});
61+
auto [index, scope] = define(defPtr->mVariableName);
62+
auto setIns = scope == Scope::kLOCAL ? kSET_LOCAL : kSET_GLOBAL;
63+
instructions().push_back(setIns);
6464
auto bytes = integerToFourBytes(index);
6565
for (Byte i : bytes)
6666
{
@@ -71,8 +71,9 @@ void Compiler::compile(ExprPtr const& expr)
7171
if (auto variablePtr = dynamic_cast<Variable const*>(exprPtr))
7272
{
7373
auto const name = variablePtr->name();
74-
auto index = mSymbolTable.at(name).second;
75-
instructions().push_back(kGET_GLOBAL);
74+
auto [index, scope] = getIndex(name);
75+
auto getIns = scope == Scope::kLOCAL ? kGET_LOCAL : kGET_GLOBAL;
76+
instructions().push_back(getIns);
7677
auto bytes = integerToFourBytes(index);
7778
for (Byte i : bytes)
7879
{
@@ -133,14 +134,18 @@ void Compiler::compile(ExprPtr const& expr)
133134
{
134135
// FIXME: find a place for function def.
135136
mFunc = FuncInfo{};
137+
auto const& args = lambdaPtr->mArguments.first;
138+
for (auto const& arg : args)
139+
{
140+
auto [idx, scope] = define(arg);
141+
ASSERT(scope == Scope::kLOCAL);
142+
}
136143
compile(lambdaPtr->mBody);
137144
instructions().push_back(kRET);
138145
auto funcInstructions = mFunc.value().first;
139146
mFunc = {};
140-
141147
auto const index = mCode.constantPool.size();
142-
auto const nbArgs = std::get_if<std::string>(&lambdaPtr->mArguments) ? 1 : std::get_if<1>(&lambdaPtr->mArguments)->first.size();
143-
auto const funcSym = FunctionSymbol{nbArgs, /* nbLocals= */ 0, funcInstructions};
148+
auto const funcSym = FunctionSymbol{args.size(), /* nbLocals= */ 0, funcInstructions};
144149
mCode.constantPool.push_back(funcSym);
145150
instructions().push_back(kCONST);
146151
auto bytes = integerToFourBytes(index);

test/lisp/testCompiler.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ TEST(Compiler, lambda0)
151151
EXPECT_EQ(output, "Function getNum\n");
152152
}
153153

154-
#if 0
155154
TEST(Compiler, lambda1)
156155
{
157156
Compiler c{};
@@ -172,4 +171,3 @@ TEST(Compiler, lambda1)
172171
std::string output = testing::internal::GetCapturedStdout();
173172
EXPECT_EQ(output, "Function identity\n");
174173
}
175-
#endif

0 commit comments

Comments
 (0)