Removed language/culebra

pull/38/head
yhirose 7 years ago
parent deac9d4c42
commit 14c0651f1f
  1. 1
      CMakeLists.txt
  2. 11
      language/culebra/CMakeLists.txt
  3. 41
      language/culebra/cul.vim
  4. 1005
      language/culebra/culebra.h
  5. 22
      language/culebra/culebra.sln
  6. 93
      language/culebra/culebra.vcxproj
  7. 1970
      language/culebra/linenoise.hpp
  8. 316
      language/culebra/main.cc
  9. 17
      language/culebra/samples/closure.cul
  10. 17
      language/culebra/samples/fib.cul
  11. 17
      language/culebra/samples/fizzbuzz.cul
  12. 248
      language/culebra/samples/test.cul

@ -70,5 +70,4 @@ add_subdirectory(example)
if(NOT MSVC)
add_subdirectory(lint)
add_subdirectory(language/pl0)
add_subdirectory(language/culebra)
endif()

@ -1,11 +0,0 @@
cmake_minimum_required(VERSION 2.8)
include_directories(../..)
if(MSVC)
add_compile_options(${cxx11_options} /W3)
add_definitions(-DUNICODE)
else()
add_compile_options(${cxx11_options})
endif()
add_executable(culebra main.cc)

@ -1,41 +0,0 @@
syn match culOperator "\%(+\|-\|/\|*\|=\|\^\|&\||\|!\|>\|<\|%\)=\?"
syn match culDecNumber "\<[0-9][0-9_]*"
syn match culFuncCall "\w\(\w\)*("he=e-1,me=e-1
syn match culError ";"
syn match culError "\s*$"
syn match culLineComment "\(\/\/\|#\).*" contains=@Spell,javaScriptCommentTodo
syn keyword culFunction fn
syn keyword culSelf self
syn keyword culConditional if else
syn keyword culRepeat while
syn keyword culReturn return
syn keyword culDebugger debugger
syn keyword culBoolean true false
syn keyword culCommentTodo TODO FIXME XXX TBD contained
syn keyword culStorage mut
syn region culStringS start=+'+ skip=+\\\\\|\\'+ end=+'\|$+
syn region culStringD start=+"+ skip=+\\\\\|\\"+ end=+"\|$+
syn region culComment start="/\*" end="\*/" contains=@Spell,javaScriptCommentTodo
hi def link culBoolean Boolean
hi def link culComment Comment
hi def link culCommentTodo Todo
hi def link culConditional Conditional
hi def link culDecNumber Number
hi def link culFuncCall Function
hi def link culFunction Type
hi def link culLineComment Comment
hi def link culOperator Operator
hi def link culRepeat Repeat
hi def link culReturn Statement
hi def link culDebugger Debug
hi def link culSelf Constant
hi def link culStorage StorageClass
hi def link culStringD String
hi def link culStringS String
hi def link culError Error
let b:current_syntax = "cul"

File diff suppressed because it is too large Load Diff

@ -1,22 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "culebra", "culebra.vcxproj", "{F85B641A-7538-4809-8175-C528FF632CF6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F85B641A-7538-4809-8175-C528FF632CF6}.Debug|Win32.ActiveCfg = Debug|Win32
{F85B641A-7538-4809-8175-C528FF632CF6}.Debug|Win32.Build.0 = Debug|Win32
{F85B641A-7538-4809-8175-C528FF632CF6}.Release|Win32.ActiveCfg = Release|Win32
{F85B641A-7538-4809-8175-C528FF632CF6}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -1,93 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\peglib.h" />
<ClInclude Include="culebra.h" />
<ClInclude Include="linenoise.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cc" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F85B641A-7538-4809-8175-C528FF632CF6}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<ProjectName>culebra</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>../..</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

File diff suppressed because it is too large Load Diff

@ -1,316 +0,0 @@
#include "culebra.h"
#include "linenoise.hpp"
#include <fstream>
#include <iomanip>
#include <iostream>
#include <vector>
using namespace peg;
using namespace peg::udl;
using namespace std;
bool read_file(const char* path, vector<char>& buff)
{
ifstream ifs(path, ios::in|ios::binary);
if (ifs.fail()) {
return false;
}
auto size = static_cast<unsigned int>(ifs.seekg(0, ios::end).tellg());
if (size > 0) {
buff.resize(size);
ifs.seekg(0, ios::beg).read(&buff[0], static_cast<streamsize>(buff.size()));
}
return true;
}
struct CommandLineDebugger
{
void operator()(const Ast& ast, culebra::Environment& env, bool force_to_break) {
if (quit) {
return;
}
if ((command_ == "n" && env.level <= level_) ||
(command_ == "s") ||
(command_ == "o" && env.level < level_)) {
force_to_break = true;
}
if (force_to_break) {
static auto show_initial_usage = true;
if (show_initial_usage) {
show_initial_usage = false;
usage();
}
show_lines(ast);
for (;;) {
cout << endl << "debug> ";
string s;
std::getline(cin, s);
istringstream is(s);
is >> command_;
if (command_ == "h") {
usage();
} else if (command_ == "l") {
is >> display_lines_;
show_lines(ast);
} else if (command_ == "p") {
string symbol;
is >> symbol;
print(ast, env, symbol);
} else if (command_ == "c") {
break;
} else if (command_ == "n") {
break;
} else if (command_ == "s") {
break;
} else if (command_ == "o") {
break;
} else if (command_ == "q") {
quit = true;
break;
}
}
level_ = env.level;;
}
}
void show_lines(const Ast& ast) {
prepare_cache(ast.path);
cout << endl << "Break in " << ast.path << ":" << ast.line << endl;
auto count = get_line_count(ast.path);
auto lines_ahead = (size_t)((display_lines_ - .5) / 2);
auto start = (size_t)max((int)ast.line - (int)lines_ahead, 1);
auto end = min(start + display_lines_, count);
auto needed_digits = to_string(count).length();
for (auto l = start; l < end; l++) {
auto s = get_line(ast.path, l);
if (l == ast.line) {
cout << "> ";
} else {
cout << " ";
}
cout << setw(needed_digits) << l << " " << s << endl;
}
}
shared_ptr<Ast> find_function_node(const Ast& ast) {
auto node = ast.parent;
while (node->parent && node->tag != "FUNCTION"_) {
node = node->parent;
}
return node;
}
void enum_identifiers(const Ast& ast, set<string>& references) {
for (auto node: ast.nodes) {
switch (node->tag) {
case "IDENTIFIER"_:
references.insert(node->token);
break;
case "FUNCTION"_:
break;
default:
enum_identifiers(*node, references);
break;
}
}
}
void print(const Ast& ast, culebra::Environment& env, const string& symbol) {
if (symbol.empty()) {
print_all(ast, env);
} else if (env.has(symbol)) {
cout << symbol << ": " << env.get(symbol).str() << endl;
} else {
cout << "'" << symbol << "'" << "is not undefined." << endl;
}
}
void print_all(const Ast& ast, culebra::Environment& env) {
auto node = find_function_node(ast);
set<string> references;
enum_identifiers(*node, references);
for (const auto& symbol: references) {
if (env.has(symbol)) {
const auto& val = env.get(symbol);
if (val.type != culebra::Value::Function) {
cout << symbol << ": " << val.str() << endl;
}
}
}
}
size_t get_line_count(const string& path) {
return sources_[path].size();
}
string get_line(const string& path, size_t line) {
const auto& positions = sources_[path];
auto idx = line - 1;
auto first = idx > 0 ? positions[idx - 1] : 0;
auto last = positions[idx];
auto size = last - first;
string s(size, 0);
ifstream ifs(path, ios::in | ios::binary);
ifs.seekg(first, ios::beg).read((char*)s.data(), static_cast<streamsize>(s.size()));
size_t count = 0;
auto rit = s.rbegin();
while (rit != s.rend()) {
if (*rit == '\n') {
count++;
}
++rit;
}
s = s.substr(0, s.size() - count);
return s;
}
void prepare_cache(const string& path) {
auto it = sources_.find(path);
if (it == sources_.end()) {
vector<char> buff;
read_file(path.c_str(), buff);
auto& positions = sources_[path];
auto i = 0u;
for (; i < buff.size(); i++) {
if (buff[i] == '\n') {
positions.push_back(i + 1);
}
}
positions.push_back(i);
}
}
void usage() {
cout << "Usage: (c)ontinue, (n)ext, (s)tep in, step (o)out, (p)ring, (l)ist, (q)uit" << endl;
}
bool quit = false;
string command_;
size_t level_ = 0;
size_t display_lines_ = 4;
map<string, vector<size_t>> sources_;
};
int repl(shared_ptr<culebra::Environment> env, bool print_ast)
{
for (;;) {
auto line = linenoise::Readline("cul> ");
if (line == "exit" || line == "quit") {
break;
}
if (!line.empty()) {
vector<string> msgs;
auto ast = culebra::parse("(repl)", line.data(), line.size(), msgs);
if (ast) {
if (print_ast) {
cout << peg::ast_to_s(ast);
}
culebra::Value val;
if (interpret(ast, env, val, msgs)) {
cout << val << endl;
linenoise::AddHistory(line.c_str());
continue;
}
}
for (const auto& msg : msgs) {
cout << msg << endl;;
}
}
}
return 0;
}
int main(int argc, const char** argv)
{
auto print_ast = false;
auto shell = false;
auto debug = false;
vector<const char*> path_list;
int argi = 1;
while (argi < argc) {
auto arg = argv[argi++];
if (string("--shell") == arg) {
shell = true;
} else if (string("--ast") == arg) {
print_ast = true;
} else if (string("--debug") == arg) {
debug = true;
} else {
path_list.push_back(arg);
}
}
if (!shell) {
shell = path_list.empty();
}
try {
auto env = make_shared<culebra::Environment>();
setup_built_in_functions(*env);
for (auto path: path_list) {
vector<char> buff;
if (!read_file(path, buff)) {
cerr << "can't open '" << path << "'." << endl;
return -1;
}
vector<string> msgs;
auto ast = culebra::parse(path, buff.data(), buff.size(), msgs);
if (ast) {
if (print_ast) {
cout << peg::ast_to_s(ast);
}
culebra::Value val;
auto dbg = debug ? CommandLineDebugger() : culebra::Debugger();
if (interpret(ast, env, val, msgs, dbg)) {
return 0;
}
}
for (const auto& msg : msgs) {
cerr << msg << endl;
}
return -1;
}
if (shell) {
repl(env, print_ast);
}
} catch (exception& e) {
cerr << e.what() << endl;
return -1;
}
return 0;
}
// vim: et ts=4 sw=4 cin cino={1s ff=unix

@ -1,17 +0,0 @@
/*
* Closure test
*/
make_func = fn (mut x) {
mut n = 100
fn () {
n = n + 1
x = x + 1 + n
}
}
f = make_func(10)
puts("1: { f() }")
puts("2: { f() }")
puts("3: { f() }")

@ -1,17 +0,0 @@
/*
* Fibonacci
*/
fib = fn (x) {
if x < 2 {
x
} else {
self(x - 2) + self(x -1)
}
}
mut i = 0
while i < 30 {
puts("{i}: {fib(i)}")
i = i + 1
}

@ -1,17 +0,0 @@
/*
* Fizz Buzz
*/
mut i = 1
while i < 24 {
if i % 15 == 0 {
puts('FizzBuzz')
} else if i % 5 == 0 {
puts('Buzz')
} else if i % 3 == 0 {
puts('Fizz')
} else {
puts(i)
}
i = i + 1
}

@ -1,248 +0,0 @@
/*
* Unit tests
*/
test_call = fn () {
ret = fn(){[1,fn(){[4,5,6]},3]}()[1]()[1]
assert(ret == 5)
}
test_return = fn () {
f = fn (x) {
if x % 2 {
return 'odd'
}
'even'
}
assert(f(3) == 'odd')
assert(f(4) == 'even')
mut val = 0
f2 = fn () {
val = 1
return // comment
val = 2
}
f2()
assert(val == 1)
}
test_nil = fn () {
assert(nil == nil)
assert(!(nil != nil))
a = nil
assert(a == nil)
assert(!(a != nil))
assert(!(a <= nil))
assert(!(a < nil))
assert(!(a >= nil))
assert(!(a > nil))
assert(nil == a)
assert(!(nil != a))
assert(!(nil <= a))
assert(!(nil < a))
assert(!(nil >= a))
assert(!(nil > a))
}
test_closure = fn () {
make_func = fn (mut x) {
mut n = 100
fn () {
n = n + 1
x = x + 1 + n
}
}
f = make_func(10)
f()
f()
ret = f()
assert(ret == 319)
}
test_array = fn () {
a = [1,2,3]
assert(a.size() == 3)
a.push(4)
assert(a.size() == 4)
b = []
assert(b.size() == 0)
c = [1]
assert(c.size() == 1)
d = [1,2,3](5, 0)
assert(d.size() == 5 && d[-1] == 0)
e = [1,2,3](2)
assert(e.size() == 3 && e[-1] == 3)
f = [1,2,3](5)
assert(f.size() == 5 && f[-1] == nil)
}
g_ = 1
test_function = fn () {
a = 1
make = fn () {
b = 1
fn (c) {
g_ + a + b + c
}
}
f = make()
assert(f(1) == 4)
}
test_object = fn () {
n = 1
o = {
n: 123,
s: 'str',
f1: fn (x) { x + this.n },
f2: fn (x) { x + n }
}
assert(o.size() == 4)
assert(o.f1(10) == 133)
assert(o.f2(10) == 11)
a = {}
a.b = 1
assert(a.a == nil)
assert(a.b == 1)
assert(a.size() == 1)
}
test_object_factory = fn () {
ctor = fn (init) {
mut n = init
{
add: fn (x) {
n = n + x
},
sub: fn (x) {
n = n - x
},
val: fn () {
n
}
}
}
calc = ctor(10)
assert(calc.val() == 10)
assert(calc.add(1) == 11)
assert(calc.sub(1) == 10)
}
test_class = fn () {
// TODO: support 'prototype' property
Car = {
new: fn(miles_per_run) {
mut total_miles = 0
{
run: fn (times) {
total_miles = total_miles + miles_per_run * times
},
total: fn () {
total_miles
}
}
}
}
car = Car.new(5)
car.run(1)
car.run(2)
assert(car.total() == 15)
}
test_sum = fn () {
mut i = 1
mut ret = 0
while i <= 10 {
ret = ret + i
i = i + 1
}
assert(ret == 55)
}
test_fib = fn () {
fib = fn (x) {
if x < 2 {
x
} else {
self(x - 2) + self(x -1)
}
}
ret = fib(15)
assert(ret == 610)
}
test_interpolated_string = fn () {
hello = "Hello"
world = "World!"
ret = "{hello} {world}"
assert(ret == 'Hello World!')
}
test_lexical_scope = fn () {
a = 0
{
let a = 1;
assert(a == 1)
}
assert(a == 0)
mut b = 0
{
b = 1;
assert(b == 1)
}
assert(b == 1)
c = 0
{
let mut c = 0;
c = 1
assert(c == 1)
}
assert(c == 0)
obj = {
name: 'object'
}
assert(obj.name == 'object')
}
debugger
test_call()
test_return()
test_closure()
test_nil()
test_array()
test_function()
test_object()
test_object_factory()
test_class()
debugger
test_sum()
test_fib()
test_interpolated_string()
test_lexical_scope()
return // end
Loading…
Cancel
Save