.rsconscache
sclpl
source/lexer.c
+project.vim
TESTOBJS = tests/atf.o \
tests/sclpl/main.o
-.PHONY: all options tests specs
-all: sclpl specs tests
+.PHONY: all tests specs
+all: sclpl tests specs
lib${BIN}.a: ${OBJS}
${AR} ${ARFLAGS} $@ $^
${BIN}: lib${BIN}.a
${LD} ${LDFLAGS} -o $@ $^
-${TESTBIN}: ${TESTOBJS}
- ${LD} ${LDFLAGS} -o $@ $^
+#${TESTBIN}: ${TESTOBJS}
+# ${LD} ${LDFLAGS} -o $@ $^
-tests: $(TESTBIN)
- ./$<
+#tests: ${TESTBIN}
+# ./$<
specs: $(BIN)
rspec --pattern 'spec/**{,/*/**}/*_spec.rb' --format documentation
"," { return T_COMMA; }
"'" { return T_SQUOTE; }
":" { return T_COLON; }
+"&" { return T_AMP; }
\\. { Value.character = yytext[1]; return T_CHAR; }
\\space { Value.character = ' '; return T_CHAR; }
static AST* expr_block(Parser* p);
static AST* token_to_tree(Tok* tok);
static AST* func_app(Parser* p, AST* fn);
+static void optional_type(Parser* p);
// Parsing Routines
static void parser_free(void* obj);
if (peek(p)->type == T_LPAR) {
expr = function(p);
} else {
+ optional_type(p);
expr = expression(p);
expect(p, T_END);
}
expect(p, T_LPAR);
while(peek(p)->type != T_RPAR) {
func_add_arg(func, Ident(expect(p,T_ID)));
+ optional_type(p);
if(peek(p)->type != T_RPAR)
expect(p, T_COMMA);
}
expect(p, T_RPAR);
+ optional_type(p);
func_set_body(func, expr_block(p));
expect(p, T_END);
return func;
return app;
}
+static void optional_type(Parser* p)
+{
+ if (accept(p, T_COLON)) {
+ expect(p, T_ID);
+ /* array type */
+ if (accept(p,T_LBRACK)) {
+ accept(p, T_INT);
+ expect(p, T_RBRACK);
+ /* reference type */
+ } else if (accept(p, T_AMP)) {
+
+ }
+ }
+}
+
/* Parsing Routines
*****************************************************************************/
Parser* parser_new(char* prompt, FILE* input)
case T_ID: return "T_ID";
case T_END: return "T_END";
case T_COLON: return "T_COLON";
+ case T_AMP: return "T_AMP";
case T_SQUOTE: return "T_SQUOTE";
case T_DQUOTE: return "T_DQUOTE";
case T_END_FILE: return "T_END_FILE";
*****************************************************************************/
typedef enum {
T_ID, T_CHAR, T_INT, T_FLOAT, T_BOOL, T_STRING, T_LBRACE, T_RBRACE, T_LBRACK,
- T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_SQUOTE, T_DQUOTE, T_END, T_COLON,
+ T_RBRACK, T_LPAR, T_RPAR, T_COMMA, T_SQUOTE, T_DQUOTE, T_END, T_COLON, T_AMP,
T_REQUIRE, T_DEF, T_IF, T_FN, T_THEN, T_ELSE, T_END_FILE
} TokType;
/* Definition Node */
struct {
char* name;
+ struct AST* type;
struct AST* value;
} def;
/* If Expression */
expect(ast('def foo 123;')).to eq([ ['def', 'foo', 'T_INT:123'] ])
end
+ it "should error on missing type for definiton" do
+ expect{ast('def foo : 123;')}.to raise_error /Error/
+ end
+
+ it "should parse a value definition with type annotation" do
+ expect(ast('def foo:int 123;')).to eq([ ['def', 'foo', 'T_INT:123'] ])
+ end
+
it "should parse a function definition" do
expect(ast('def foo() 123;')).to eq([
['def', 'foo', ['fn', [],
["let", ["$:0", "T_INT:123"], "$:0"]]] ])
end
+ it "should parse a function definition with return type annotation" do
+ expect(ast('def foo():int 123;')).to eq([
+ ['def', 'foo', ['fn', [],
+ ["let", ["$:0", "T_INT:123"], "$:0"]]] ])
+ end
+
+ it "should error on a function definition with missing return type" do
+ pending("TODO: fix the error message here")
+ expect(ast('def foo() : 123;')).to raise_error /Error/
+ end
+
it "should parse a function definition with multiple expressions in the body" do
expect(ast('def foo() 123 321;')).to eq([
['def', 'foo', ['fn', [],
["let", ["$:0", "T_INT:123"], "$:0"]]])
end
+ it "should parse a function with no params and a return type annotation" do
+ expect(ast('fn():int 123;')).to eq([
+ ["fn", [],
+ ["let", ["$:0", "T_INT:123"], "$:0"]]])
+ end
+
it "should parse a function with one param" do
expect(ast('fn(a) 123;')).to eq([
["fn", ["T_ID:a"],
["let", ["$:0", "T_INT:123"], "$:0"]]])
end
+ it "should parse a function with one param with type annotation" do
+ expect(ast('fn(a:int) 123;')).to eq([
+ ["fn", ["T_ID:a"],
+ ["let", ["$:0", "T_INT:123"], "$:0"]]])
+ end
+
it "should parse a function with two params" do
expect(ast('fn(a,b) 123;')).to eq([
["fn", ["T_ID:a", "T_ID:b"],