mirror of
https://github.com/Kugelschieber/asl.git
synced 2026-01-18 12:00:25 +00:00
Fixed binary buildin functions and tests.
This commit is contained in:
@@ -2,8 +2,6 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"tokenizer"
|
"tokenizer"
|
||||||
"types"
|
"types"
|
||||||
)
|
)
|
||||||
@@ -369,24 +367,19 @@ func (c *Compiler) parseFunctionCall(out bool, name string) string {
|
|||||||
output := ""
|
output := ""
|
||||||
|
|
||||||
c.expect("(")
|
c.expect("(")
|
||||||
paramsStr, params, paramCount := c.parseParameter(false)
|
paramsStr, paramCount := c.parseParameter(false)
|
||||||
c.expect(")")
|
c.expect(")")
|
||||||
|
|
||||||
// buildin function
|
// buildin function
|
||||||
buildin := types.GetFunction(name)
|
buildin := types.GetFunction(name)
|
||||||
|
|
||||||
if buildin != nil {
|
if buildin != nil {
|
||||||
// check parameter count
|
|
||||||
if paramCount < buildin.ArgsLeft+buildin.ArgsRight {
|
|
||||||
panic(errors.New("Function expected " + strconv.Itoa(buildin.ArgsLeft+buildin.ArgsRight) + " parameter but found " + strconv.Itoa(paramCount)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if buildin.Type == types.NULL {
|
if buildin.Type == types.NULL {
|
||||||
output = name
|
output = name
|
||||||
} else if buildin.Type == types.UNARY {
|
} else if buildin.Type == types.UNARY {
|
||||||
output = c.parseUnaryFunction(name, paramsStr, paramCount)
|
output = c.parseUnaryFunction(name, paramsStr, paramCount)
|
||||||
} else {
|
} else {
|
||||||
output = c.parseBinaryFunction(name, params, buildin)
|
output = c.parseBinaryFunction(name, paramsStr, buildin, paramCount)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
output = "[" + paramsStr + "] call " + name
|
output = "[" + paramsStr + "] call " + name
|
||||||
@@ -411,63 +404,37 @@ func (c *Compiler) parseUnaryFunction(name, paramsStr string, paramCount int) st
|
|||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) parseBinaryFunction(name string, params []string, buildin *types.FunctionType) string {
|
func (c *Compiler) parseBinaryFunction(name string, leftParamsStr string, buildin *types.FunctionType, paramCount int) string {
|
||||||
// FIXME number of elements can't be determined if array is parameter
|
|
||||||
output := ""
|
output := ""
|
||||||
|
|
||||||
fmt.Println(len(params))
|
c.next()
|
||||||
fmt.Println(buildin.ArgsLeft)
|
rightParamsStr, rightParamCount := c.parseParameter(false)
|
||||||
fmt.Println(buildin.ArgsRight)
|
c.expect(")")
|
||||||
fmt.Println(params[0])
|
|
||||||
fmt.Println(params[1])
|
|
||||||
fmt.Println(params[2])
|
|
||||||
|
|
||||||
if buildin.ArgsLeft == 1 {
|
if paramCount > 1 {
|
||||||
output = params[0] + " "
|
leftParamsStr = "[" + leftParamsStr + "]"
|
||||||
} else {
|
|
||||||
output = "["
|
|
||||||
|
|
||||||
for i := 0; i < buildin.ArgsLeft; i++ {
|
|
||||||
output += params[i]
|
|
||||||
|
|
||||||
if i != buildin.ArgsLeft-1 {
|
|
||||||
output += ","
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output += "] "
|
|
||||||
}
|
}
|
||||||
|
|
||||||
output += name
|
if rightParamCount > 1 {
|
||||||
|
rightParamsStr = "[" + rightParamsStr + "]"
|
||||||
|
}
|
||||||
|
|
||||||
if buildin.ArgsRight-buildin.ArgsLeft == 1 {
|
if paramCount > 0 {
|
||||||
output += " " + params[1]
|
output = leftParamsStr + " " + name + " " + rightParamsStr
|
||||||
} else {
|
} else {
|
||||||
output += " ["
|
output = name + " " + rightParamsStr
|
||||||
|
|
||||||
for i := buildin.ArgsLeft; i < buildin.ArgsRight; i++ {
|
|
||||||
output += params[i]
|
|
||||||
|
|
||||||
if i != buildin.ArgsRight-buildin.ArgsLeft-1 {
|
|
||||||
output += ","
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output += "]"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) parseParameter(out bool) (string, []string, int) {
|
func (c *Compiler) parseParameter(out bool) (string, int) {
|
||||||
output := ""
|
output := ""
|
||||||
params := make([]string, 0)
|
|
||||||
count := 0
|
count := 0
|
||||||
|
|
||||||
for !c.accept(")") {
|
for !c.accept(")") {
|
||||||
expr := c.parseExpression(out)
|
expr := c.parseExpression(out)
|
||||||
output += expr
|
output += expr
|
||||||
params = append(params, expr)
|
|
||||||
count++
|
count++
|
||||||
|
|
||||||
if !c.accept(")") {
|
if !c.accept(")") {
|
||||||
@@ -480,7 +447,7 @@ func (c *Compiler) parseParameter(out bool) (string, []string, int) {
|
|||||||
c.appendOut(output, false)
|
c.appendOut(output, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return output, params, count
|
return output, count
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Compiler) parseExpression(out bool) string {
|
func (c *Compiler) parseExpression(out bool) string {
|
||||||
|
|||||||
@@ -5,6 +5,11 @@ import (
|
|||||||
"parser"
|
"parser"
|
||||||
"testing"
|
"testing"
|
||||||
"tokenizer"
|
"tokenizer"
|
||||||
|
"types"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
types_file = "../../test/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParserDeclaration(t *testing.T) {
|
func TestParserDeclaration(t *testing.T) {
|
||||||
@@ -91,12 +96,32 @@ func TestParserFunctionCall(t *testing.T) {
|
|||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*func TestParserBuildinFunctionCall(t *testing.T) {
|
func TestParserNullBuildinFunctionCall(t *testing.T) {
|
||||||
got := getCompiled(t, "../../test/parser_buildin_func.asl")
|
types.LoadTypes(types_file)
|
||||||
want := "_x = (([player, foo] getVar bar) setHit [\"head\", \"tail\"]);\r\n"
|
|
||||||
|
got := getCompiled(t, "../../test/parser_null_buildin_func.asl")
|
||||||
|
want := "_volume = (radioVolume);\r\n"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
func TestParserUnaryBuildinFunctionCall(t *testing.T) {
|
||||||
|
types.LoadTypes(types_file)
|
||||||
|
|
||||||
|
got := getCompiled(t, "../../test/parser_unary_buildin_func.asl")
|
||||||
|
want := "_isReady = (unitReady soldier);\r\n"
|
||||||
|
|
||||||
|
equal(t, got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParserBinaryBuildinFunctionCall(t *testing.T) {
|
||||||
|
types.LoadTypes(types_file)
|
||||||
|
|
||||||
|
got := getCompiled(t, "../../test/parser_binary_buildin_func.asl")
|
||||||
|
want := "someCar setHit [\"motor\", 1];\r\n"
|
||||||
|
|
||||||
|
equal(t, got, want)
|
||||||
|
}
|
||||||
|
|
||||||
func TestParserOperator(t *testing.T) {
|
func TestParserOperator(t *testing.T) {
|
||||||
got := getCompiled(t, "../../test/parser_operator.asl")
|
got := getCompiled(t, "../../test/parser_operator.asl")
|
||||||
@@ -154,12 +179,14 @@ func TestParserInlineCode(t *testing.T) {
|
|||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*func TestParserPreprocessor(t *testing.T) {
|
func TestParserPreprocessor(t *testing.T) {
|
||||||
|
types.LoadTypes(types_file)
|
||||||
|
|
||||||
got := getCompiled(t, "../../test/tokenizer_preprocessor.asl")
|
got := getCompiled(t, "../../test/tokenizer_preprocessor.asl")
|
||||||
want := "\r\n#define HELLO_WORLD \"Hello World!\"\r\nhint HELLO_WORLD;\r\n"
|
want := "\r\n#define HELLO_WORLD \"Hello World!\"\r\nhint HELLO_WORLD;\r\n"
|
||||||
|
|
||||||
equal(t, got, want)
|
equal(t, got, want)
|
||||||
}*/
|
}
|
||||||
|
|
||||||
func TestParserExpressionArray(t *testing.T) {
|
func TestParserExpressionArray(t *testing.T) {
|
||||||
got := getCompiled(t, "../../test/parser_expression_array.asl")
|
got := getCompiled(t, "../../test/parser_expression_array.asl")
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ func TestTokenizerInlineCode(t *testing.T) {
|
|||||||
|
|
||||||
func TestTokenizerPreprocessor(t *testing.T) {
|
func TestTokenizerPreprocessor(t *testing.T) {
|
||||||
got := getTokens(t, "../../test/tokenizer_preprocessor.asl")
|
got := getTokens(t, "../../test/tokenizer_preprocessor.asl")
|
||||||
want := []string{"#define HELLO_WORLD \"Hello World!\"", "hint", "(", ")", "(", "HELLO_WORLD", ")", ";"}
|
want := []string{"#define HELLO_WORLD \"Hello World!\"", "hint", "(", "HELLO_WORLD", ")", ";"}
|
||||||
|
|
||||||
compareLength(t, &got, &want)
|
compareLength(t, &got, &want)
|
||||||
compareTokens(t, &got, &want)
|
compareTokens(t, &got, &want)
|
||||||
|
|||||||
18
src/types/loader_test.go
Normal file
18
src/types/loader_test.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package types_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTypesGetFunction(t *testing.T) {
|
||||||
|
if err := types.LoadTypes("../../test/types"); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
function := types.GetFunction("hint")
|
||||||
|
|
||||||
|
if function == nil {
|
||||||
|
t.Error("Function 'hint' not found in type list")
|
||||||
|
}
|
||||||
|
}
|
||||||
1
test/parser_binary_buildin_func.asl
Normal file
1
test/parser_binary_buildin_func.asl
Normal file
@@ -0,0 +1 @@
|
|||||||
|
setHit(someCar)("motor", 1);
|
||||||
@@ -1 +0,0 @@
|
|||||||
var _x = setHit(getVar(player, foo, bar), "head", "tail");
|
|
||||||
1
test/parser_null_buildin_func.asl
Normal file
1
test/parser_null_buildin_func.asl
Normal file
@@ -0,0 +1 @@
|
|||||||
|
var _volume = radioVolume();
|
||||||
1
test/parser_unary_buildin_func.asl
Normal file
1
test/parser_unary_buildin_func.asl
Normal file
@@ -0,0 +1 @@
|
|||||||
|
var _isReady = unitReady(soldier);
|
||||||
2198
test/types
Normal file
2198
test/types
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user