using System; using System.Collections.Generic; using System.Linq; using System.Text; using NUnit.Framework; using System.IO; using OCamlC.Lex; using OCamlC.Parse; using OCamlC.AST; namespace OCamlC.Tests { [TestFixture] public class LexerBehaviour1 { [Test] public void Test1ThroughConstraint() { const string c_helloworld = "print_string \"hello world\\n\";;"; Lexer lex = new Lexer(); StringReader infile = new StringReader(c_helloworld); Assert.That(lex.Lex(infile), Tokens.Are( TokenType.ID, "print_string", TokenType.STRING, "hello world\n", TokenType.KW_SEMISEMI )); } [Test] public void TestIdentifiers() { const string c_ids = @"hello h311o num_0123456789_end id' id's _id"; StringReader infile = new StringReader(c_ids); Assert.That(new Lexer().Lex(infile), Tokens.Are( TokenType.ID, "hello", TokenType.ID, "h311o", TokenType.ID, "num_0123456789_end", TokenType.ID, "id'", TokenType.ID, "id's", TokenType.ID, "_id" )); } [Test] public void TestIntLiterals() { // XXX test termination, eg octal sequence with a 9 // or hex sequence with an m. // XXX test missing number, eg a bare "0x". // XXX what's the maximum integer value? string[] c_nums = new string[] { "0", "-0", "123", "123_", "-1_2_3", // XXX other bases //"0xff", "0Xed", "-0x123", //"0O76", "0o4", "-0O3", //"0b1", "-0B0111_0001_1101_011" }; StringReader infile = new StringReader(string.Join(" ", c_nums)); Assert.That(new Lexer().Lex(infile), Tokens.Are( TokenType.INT, 0, "0", TokenType.INT, 0, "-0", TokenType.INT, 123, "123", TokenType.INT, 123, "123_", TokenType.INT, -123, "-1_2_3" )); } [Test] public void TestFloatLiterals() { string[] c_nums = new string[] { "0.0", "-0.0", "1.23", "1.23_", "-1_2_.3", "1.1e1", "-1.1e-1", "-0.1e+2", "1.0e1_0", "1e2", "1_e_2_", "100.", "4._", // XXX from the regex in the docs, a leading _ in the // exponent should be ignored ... but for now I'll // accept it. }; StringReader infile = new StringReader(string.Join(" ", c_nums)); Assert.That(new Lexer().Lex(infile), Tokens.Are( TokenType.FLOAT, 0.0, "0.0", TokenType.FLOAT, 0.0, "-0.0", TokenType.FLOAT, 1.23, "1.23", TokenType.FLOAT, 1.23, "1.23_", TokenType.FLOAT, -12.3, "-1_2_.3", TokenType.FLOAT, 11.0, "1.1e1", TokenType.FLOAT, -0.11, "-1.1e-1", TokenType.FLOAT, -10.0, "-0.1e+2", TokenType.FLOAT, 10000000000.0, "1.0e1_0", TokenType.FLOAT, 100.0, "1e2", TokenType.FLOAT, 100.0, "1_e_2_", TokenType.FLOAT, 100.0, "100.", TokenType.FLOAT, 4.0, "4._" )); } [Test] public void TestComments() { const string c_com1 = @"one (* comment *) three one(*comment*)three one(*nested(*comment*)again*)three"; StringReader infile = new StringReader(c_com1); Assert.That(new Lexer().Lex(infile), Tokens.Are(allOfType(TokenType.ID, "one", "three", "one", "three", "one", "three" ))); } [Test] [ExpectedException(typeof(CantLexException))] public void TestMultipleCommentTerminator() { StringReader infile = new StringReader("one (* comment *) *) three"); Assert.That(new Lexer().Lex(infile), Tokens.Are( TokenType.ID, "one", TokenType.INFIXSYMBOL, "*", TokenType.ID, "three" )); } private IEnumerable allOfType(TokenType type, params string[] stringValue) { foreach (string val in stringValue) { yield return type; yield return val; } } } }