예제 #1
0
func (fs LambdaStatement) Parse(block string, lineNum int, nextBlockScanner *parser.ScanPeeker, factory *StatementFactory) (Statement, parser.SyntaxError) {
	lines := parser.Lines(block)
	factory = fetchNewFactory(factory)
	typeDef, err, rest := expressionParsing.ParseTypeDef(lines[0])
	if err != nil {
		return nil, parser.NewSyntaxError(err.Error(), lineNum, 0)
	}

	var ftd expressionParsing.FuncTypeDefinition
	var ok bool
	if ftd, ok = typeDef.(expressionParsing.FuncTypeDefinition); !ok {
		return nil, nil
	}

	var codeBlock []string
	if len(strings.TrimSpace(rest)) > 0 {
		var first string
		if len(lines) > 1 {
			return nil, parser.NewSyntaxError("Inline lambdas can only be one line", lineNum, 0)
		} else if first, rest = parser.Tokenize(rest); first != "->" {
			return nil, parser.NewSyntaxError("Misplaced tokens: "+rest, lineNum, 0)
		}
		codeBlock = []string{rest}
	} else {
		codeBlock = parser.RemoveTabs(lines[1:])
	}

	innerStatements, synErr := fetchInnerStatements(codeBlock, factory, lineNum+1)
	if synErr != nil {
		return nil, synErr
	}

	synErr = verifyInnerStatements(innerStatements, lineNum)
	if synErr != nil {
		return nil, synErr
	}

	return newLambdaStatement(lineNum, ftd, innerStatements, fs.packageLevel, fs.name), nil
}
예제 #2
0
			d, err := statementParser.Parse(code, 0, nil, factory)
			ds := d.(*LetStatement)
			Expect(err).To(BeNil())
			Expect(ds).ToNot(BeNil())
			Expect(ds.VariableName()).To(Equal("a"))
			Expect(stripWhitespace(ds.CodeBlock())).To(Equal("b+9"))
		})
		It("Should return nil for a non declaration", func() {
			code := "if true\n\t9\nelse\n\t10"
			d, err := statementParser.Parse(code, 0, nil, factory)
			Expect(err).To(BeNil())
			Expect(d).To(BeNil())
		})
	})
	Context("GenerateGo", func() {
		It("Should return proper go code", func() {
			code := "let a = 9 + 6"
			d, err := statementParser.Parse(code, 0, nil, factory)
			fm := expressionParsing.NewFunctionMap()
			gocode, returnType, err := d.GenerateGo(fm)
			Expect(err).To(BeNil())
			intType, _, _ := expressionParsing.ParseTypeDef("int32")
			Expect(returnType.GenerateGo()).To(Equal(intType.GenerateGo()))
			Expect(gocode).To(Equal("var a func() int32\na = func(){\n\treturn (9+6)\n}"))
			fd := fm.GetFunction("a")
			Expect(fd).ToNot(BeNil())
			Expect(fd.GenerateGo()).To(Equal(intType.GenerateGo()))
		})
	})
})
예제 #3
0
	. "github.com/onsi/gomega"
)

var _ = Describe("LambdaStatement", func() {
	var statementParser StatementParser
	var factory *StatementFactory
	BeforeEach(func() {
		retParser := NewReturnStatementParser()
		declParser := NewLetParser()
		statementParser = NewLambdaStatementParser()
		factory = NewStatementFactory(declParser, statementParser, retParser)
	})
	Context("Parse", func() {
		var expectedType expressionParsing.TypeDefinition
		BeforeEach(func() {
			expectedType, _, _ = expressionParsing.ParseTypeDef("func a A -> b B -> int32")
		})
		It("Should distinguish a lambda statement", func() {
			code := "func a A -> b B -> int32\n\t5+9"
			f, err := statementParser.Parse(code, 0, nil, factory)
			Expect(f).ToNot(BeNil())
			fs := f.(*LambdaStatement)
			Expect(err).To(BeNil())
			Expect(fs).ToNot(BeNil())
			Expect(fs.TypeDef.GenerateGo()).To(Equal(expectedType.GenerateGo()))
			Expect(fs.InnerStatements).ToNot(BeNil())
			Expect(fs.InnerStatements).To(HaveLen(1))
		})
		It("Should distinguish a single line lambda statement", func() {
			code := "func a A -> b B -> int32 -> 5+9"
			f, err := statementParser.Parse(code, 0, nil, factory)
예제 #4
0
			Expect(r).ToNot(BeNil())
		})
	})
	Context("GenerateGo", func() {
		var funcMap expressionParsing.FunctionMap
		BeforeEach(func() {
			funcMap = expressionParsing.NewFunctionMap()
		})
		Context("No functions", func() {
			It("Should generate the proper Go code", func() {
				code := "( 1 + 11 ) - 10 / 2"
				r, err := statementParser.Parse(code, 0, nil, factory)
				Expect(err).To(BeNil())
				genGo, returnType, err := r.GenerateGo(funcMap)
				Expect(err).To(BeNil())
				intType, _, _ := expressionParsing.ParseTypeDef("int32")
				Expect(returnType.GenerateGo()).To(Equal(intType.GenerateGo()))
				Expect(genGo).To(Equal("((1+11)-(10/2))"))
			})
			It("Should generate the proper Go code with proper numeric types", func() {
				code := "( 1b + 11b ) - 10b / 2b"
				r, err := statementParser.Parse(code, 0, nil, factory)
				Expect(err).To(BeNil())
				genGo, returnType, err := r.GenerateGo(funcMap)
				Expect(err).To(BeNil())
				intType, _, _ := expressionParsing.ParseTypeDef("int8")
				Expect(returnType.GenerateGo()).To(Equal(intType.GenerateGo()))
				Expect(genGo).To(Equal("((int8(1)+int8(11))-(int8(10)/int8(2)))"))
			})
		})
		Context("With functions", func() {